質問: ### 前提・実現したいこと ここに質問の内容を詳しく書いてください。 python でsort を使って list をソートしたいです(もしかしたらsort使わないかも) ['is', 'to', 'to', 'of', 'the', 'for', 'all', 'the', 'aid', 'This', 'time', 'good', 'come', 'people', 'theiry', 'country', 'Shakespeare'] 今現在ファイルから読み取って上のリストが入っています このようなリストをアルファベット順(大文字が絶対先に入る)。なおかつ 文字列の長さを基準に考えて出現回数の多い順に並べたいです。 例えばリストの中に 長さ6文字の単語が8個 長さ4文字の単語が4個 長さ2文字の単語が9個 長さ6文字の単語が10個 長さ1文字の単語が4個 ありましたら一番数の多い6文字をリストに入れてくという感じです。(アルファベット順で) 次は9個の2文字 次は8個の6文字という感じです。 もし個数が一緒なら長さが短い方が先にリストに入る感じです 長さ4と1なら1が先に入ります。 どのようにファンクションを作れば良いでしょうか。 ### 発生している問題・エラーメッセージ ``` エラーメッセージ ``` ### 該当のソースコード ``` ソースコード ``` ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) python 3 です ここにより詳細な情報を記載してください。
回答: > > list.sort(key=len) > > 長さ順はこれでやりました > > > なるほど。 Pythonのソートは**安定ソート**というものに分類されまして、 端的に言うと今回のケースは次のように分割して考えることができます。 ``` # 優先順位が高い条件のソートほど後に行うようにします。 lst.sort(key=...) # A) 頭文字を見て、大文字が先、小文字が後にソート lst.sort(key=...) # B) アルファベット順にソート(大文字小文字は無視) lst.sort(key=...) # C) 長さの頻度降順にソート ``` A)B)については試行錯誤してみてほしいです。 C)についてはちょっとめんどくさいので解説します。 (大文字が頭文字以外に入る余地があるのなら、A)B)は一括した方が楽でしょう。) #### **長さの頻度の得方** collections.Counterが便利です。 ``` import collections counter = collections.Counter(map(len, lst)) for l, n in counter.most_common(): print(f'{l}文字: {n}個') ``` これで頻度を counter[文字数] で獲得できます。 #### **辞書の要素でソート** 次のようにキーを与えれば良いです。 ``` lst.sort(key=lambda s: counter[len(s)], reverse=True) print(lst) ``` **追記**: lehshellさんの回答を見て、同じ頻度の『長さ』への考慮が足りなかったことに気付きました。 C)のソートは次の二段階に分けると良いですね。 ``` lst.sort(key=len) lst.sort(key=lambda s: counter[len(s)], reverse=True) print(lst) ``` あるいはキー関数でタプルを返しても良いです。 ``` lst.sort(key=lambda s: (-counter[len(s)], len(s))) print(lst) ```