質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

424閲覧

クイックソートについて

kannnn

総合スコア3

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/07/21 06:14

編集2022/07/21 06:24

クイックソートについての質問です。Colaboratory python を使用しています。

10人の国語と数学の合計を高い順に表示するためにクイックソートを作成しました。

def partition(nums, beginning, ending): i = beginning - 1 pivot = nums[ending] for j in range(beginning, ending): if nums[j] <= pivot: i += 1 nums[i], nums[j] = nums[j], nums[i] nums[i + 1], nums[ending] = nums[ending], nums[i + 1] return i+1 def quick_sort(nums, beginning, ending): if beginning < ending: pivot_index = partition(nums, beginning, ending) quick_sort(nums, beginning, pivot_index - 1) quick_sort(nums, pivot_index + 1, ending) return nums

続いて今回並び替えたいlistです

SeisekiList = [ {"NAMAE":"A ","KOKUGO":80,"SUGAKU":95}, {"NAMAE":"B","KOKUGO":75,"SUGAKU":75}, {"NAMAE":"C","KOKUGO":40,"SUGAKU":80}, {"NAMAE":"D","KOKUGO":60,"SUGAKU":60}, {"NAMAE":"E","KOKUGO":80,"SUGAKU":90}, {"NAMAE":"F","KOKUGO":95,"SUGAKU":95}, {"NAMAE":"G","KOKUGO":90,"SUGAKU":80}, {"NAMAE":"H","KOKUGO":75,"SUGAKU":85}, {"NAMAE":"I","KOKUGO":40,"SUGAKU":45}, {"NAMAE":"J","KOKUGO":80,"SUGAKU":60} ]

続いて実行前と実行後での比較しながら出力しようとしたところ、エラーが発生してしましました

for ent in SeisekiList: ent["GOKEI"]=ent["KOKUGO"]+ ent["SUGAKU"] print("===Initial===") for ent in SeisekiList: print("{:10s} {:>3d} {:3d} {:>3d}".format(ent["NAMAE"],ent["KOKUGO"],ent["SUGAKU"],ent["GOKEI"])) quick_sort(SeisekiList,0, len(SeisekiList) - 1) print("===Sorted===") for ent in SeisekiList: print("{:10s} {:>3d} {:3d} {:>3d}".format(ent["NAMAE"],ent["KOKUGO"],ent["SUGAKU"],ent["GOKEI"]))

下記エラー内容です

TypeError Traceback (most recent call last) <ipython-input-10-d6677c2a86db> in <module>() 22 for ent in SeisekiList: 23 print("{:10s} {:>3d} {:3d} {:>3d}".format(ent["NAMAE"],ent["KOKUGO"],ent["SUGAKU"],ent["GOKEI"])) ---> 24 quick_sort(SeisekiList,0, len(SeisekiList) - 1) 25 print("===Sorted===") 26 for ent in SeisekiList: 1 frames <ipython-input-10-d6677c2a86db> in quick_sort(nums, beginning, ending) 11 def quick_sort(nums, beginning, ending): 12 if beginning < ending: ---> 13 pivot_index = partition(nums, beginning, ending) 14 quick_sort(nums, beginning, pivot_index - 1) 15 quick_sort(nums, pivot_index + 1, ending) <ipython-input-10-d6677c2a86db> in partition(nums, beginning, ending) 3 pivot = nums[ending] 4 for j in range(beginning, ending): ----> 5 if nums[j] <= pivot: 6 i += 1 7 nums[i], nums[j] = nums[j], nums[i] TypeError: '<=' not supported between instances of 'dict' and 'dict'

どの部分を変えればエラーが発生せずに動くようになりますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2022/07/21 06:19

発生したエラーも質問に載せていただけますか。 載せる場合、内容は最後の行だけでなく、すべてでお願いします。。
kannnn

2022/07/21 06:25

失礼いたしました。修正完了しました。
guest

回答1

0

作成したソートは、「数値のリストを受け取って、その数値の順に並べ替える」ものであるのに対して、実際に与えているSeisekiListは、「辞書のリスト」だからでしょう。

クイックソートの方を、「dictのリストを受け取って、そのdictの指定されたキーの順に並べ替える」というものに変更すればいいのではないかと思います。
それほど大きな修正にはならないと思いますよ。


質問を受けて追記します。

ポイントは、今回比較したいのは、リストに入っているものそのものでなくて、その要素の1つであることです。

まず、quick_sort ()関数は、中に入っている数値の比較をしていないので、そのままでOKです。
1箇所している比較は、リストのインデックスですね。

実際に入れ替えをしているのは partition()関数の方ですね。

python

1def partition(nums, beginning, ending): 2 i = beginning - 1 3 pivot = nums[ending] 4 for j in range(beginning, ending): 5 if nums[j] <= pivot: 6 i += 1 7 nums[i], nums[j] = nums[j], nums[i] 8 nums[i + 1], nums[ending] = nums[ending], nums[i + 1] 9 return i+1

ここで、 iとjは インデックスですから、そのままでいいのですね。
この中で比較している場所が1箇所、「nums[j] <= pivot」これです。このときの、nums[j] はリストの要素ですから、たとえば、{"NAMAE":"A ","KOKUGO":80,"SUGAKU":95, "GOUKEI", 175}のようなdictです。これそのものを比較したいものではありませんよね。 比較したいのは、さらにこの中の"GOUKEI"の値のはずです。なのでここは、「if nums[j]["GOUKEI"] <= pivot:」 としなければなりません。
また、ここで比較しているpivotは、この前で値を入れていますが、ここも「 pivot = nums[ending]["GOUKEI"]」のように目的の値を使うようにします。
基本的にこれで済むはずです。
他の部分も含めて考えてみてください。

さらに、ここでは、"GOUKEI"を直接使いましたが、関数の引数で受け取るようにして、quick_sort関数でも受け取るようにしてやれば、国語の成績でも、算数の成績でも並べ替えられるようにできますね。

投稿2022/07/21 06:27

編集2022/07/21 12:47
TakaiY

総合スコア12765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kannnn

2022/07/21 12:07

回答ありがとうございます。返信遅れて申し訳ありません。ご回答いただいてから調べて試行錯誤したのですが、pythonを始めたばかりでよく理解できず、TakaiYさんがおっしゃっていた「dictのリストを受け取って、そのdictの指定されたキーの順に並べ替える」というのをどう表現したらいいかわかりませんでした。もしよければ一部で大丈夫ですので教えていただけると本当に助かります。
kannnn

2022/07/21 13:19

追加でのご回答ありがとうございます。無事実行して動くところまではできたのですが、出力の際”GOKEI” の部分だけがソートされ、ほかの部分が動かないのですが合計が高い順に名前と国語数学も同時にならび変えるにはどうすればいいのでしょうか?
TakaiY

2022/07/22 03:06

もしかして、「nums[i], nums[j] = nums[j], nums[i]」この部分などにも["GOUKEI"] を付けていませんか? どこに付けてどこに付けるべきでないか、ようするに、何を比較して、何を入れ替えるか、を考えてみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問