[解決済み] 2つのリスト(お互いを参照している)を全く同じ方法でソートする方法
質問
2つのリストがあるとします。
list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
を実行すると
list1.sort()
にソートされます。
[1,1,2,3,4]
を取得する方法はありますか?
list2
も同期している(つまり、項目
4
に属している。
'three'
)? つまり、期待される出力は次のようになります。
list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']
私の問題は、リストでうまく動作しているかなり複雑なプログラムがあるのですが、あるデータを参照し始める必要があることです。これは辞書にとって完璧な状況であることは分かっていますが、私はキー値をソートする必要があるので、私の処理では辞書を避けようとしています(もし私が辞書を使用しなければならないなら、私はそれを使用する方法を知っています)。
基本的にこのプログラムの本質は、データがランダムな順序で来る(上記のように)、私はそれをソートし、それを処理し、その後結果を送信する必要があります(順序は重要ではありませんが、ユーザーはどの結果がどのキーに属しているかを知る必要があります)。まず辞書に入れてからリスト1をソートすることも考えましたが、順序が維持されないと、同じ値を持つ項目を区別する方法がありません(ユーザーに結果を伝えるときに影響があるかもしれません)。 そのため、理想的には、リストを取得したら、両方のリストを一緒にソートする方法を考えたいと思っています。 これは可能でしょうか?
どのように解決するのですか?
この問題に対する古典的なアプローチの1つは、quot;decorate, sort, undecorate"というイディオムを使うことで、これは特にpythonの組み込みである
zip
という関数があります。
>>> list1 = [3,2,4,1, 1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2
('one', 'one2', 'two', 'three', 'four')
もちろん、これらはもはやリストではありませんが、重要であれば、それは簡単に改善されます。
>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']
インプレース版は3行で済みますが、私のマシンでは小さなリストではほんの少し速くなります。
>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop
一方、大きなリストでは、一行版の方が速いかもしれません。
>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop
Quantum7が指摘するように
JSFの提案
はまだ少し速いのですが、Python が
内部的には全く同じDSUイディオム
は、すべてのキーベースのソートに使用されます。ただ、ベアメタルに少し近づいただけなんです。(このことは
zip
ルーチンがあります!)
の方がいいと思います。
zip
-をベースにしたアプローチの方がより柔軟で、少し読みやすいので、私はそちらを好んでいます。
の要素がある場合は、注意が必要です。
list1
の要素を比較することになります。
list2
. もし
list2
が比較をサポートしないか、比較してもブール値を生成しない場合 (たとえば
list2
が NumPy 配列のリストである場合、これは失敗します。
list2
は比較するのに非常にコストがかかるので、とにかく比較しない方がいいかもしれません。
その場合、jfsの回答で提案されているようにインデックスをソートするか、ソートにキーとなる関数を与えて
list2
:
result1, result2 = zip(*sorted(zip(list1, list2), key=lambda x: x[0]))
また
zip(*...)
は、入力が空の場合、転置に失敗します。入力が空になる可能性がある場合、その場合は別途対処する必要があります。
関連
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み] 辞書のリストを辞書の値でソートするにはどうしたらいいですか?
-
[解決済み] 2つのリストを辞書に変換するにはどうしたらいいですか?
-
[解決済み] List<T>をオブジェクトのプロパティでソートする方法
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] リスト/タプルを指定されたインデックスにある要素でソートするには?
-
[解決済み] なぜ[]はlist()よりも速いのですか?
-
[解決済み] 複数の属性でリストを並べ替える?
-
[解決済み】2つのリストを並列に反復処理する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python百行で韓服サークルの画像クロールを実現する
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonコードの可読性を向上させるツール「pycodestyle」の使い方を詳しく解説します
-
[解決済み] データ型が理解できない
-
[解決済み】 NameError: グローバル名 'xrange' は Python 3 で定義されていません。
-
[解決済み] builtins.TypeError: strでなければならない、bytesではない
-
[解決済み] TypeError: 'DataFrame' オブジェクトは呼び出し可能ではない
-
[解決済み】ValueError: pickleプロトコルがサポートされていません。3、python2 pickleはpython3 pickleでダンプしたファイルを読み込むことができない?
-
[解決済み】 TypeError: += でサポートされていないオペランド型: 'int' および 'list' です。
-
[解決済み】pythonの*演算子の正式名称は?