リスト/タプルのタプルを特定のインデックスの要素でソートする方法は?


658

次のように、リストのリストまたはタプルのリストにデータがあります。

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

そして、サブセットの2番目の要素でソートしたいと思います。つまり、2がfrom (1,2,3)である2,5,8でソートすると、5はfrom (4,5,6)です。これを行う一般的な方法は何ですか?リストにタプルまたはリストを保存する必要がありますか?


51
「タプルまたはリストをリストに保存する必要がありますか?」に関しては、原則として、物事をできるだけ不変にすることです。サブリストを適切に変更する必要がない場合は、それらをタプルにします。
Matthew Flaschen 2010年

回答:


1116
sorted_by_second = sorted(data, key=lambda tup: tup[1])

または:

data.sort(key=lambda tup: tup[1])  # sorts in place

10
それを大きいものから小さいものに並べ替える方法はありますか?
billwild 2012

63
@billwild:ヘルプ(ソート)。reverse = True。
スティーブン

34
:itemgetterを使用すると、より高速かつ簡単です@Stephen key=itemgetter(1)と、ファイルの先頭に:from operator import itemgetter
Joschua

3
@Cemre 2番目の例と同様に、ラムダ関数をパラメーターとして受け取るPython sortListオブジェクトのメソッドを次に示しkeyます。君はそれに名前を付けることtup、またはt、など何でも、それは仕事、まだよ。tupここではリストのタプルのインデックスを指定しているため1、元のリストのタプルの2番目の値(2, 5, 8)によって並べ替えが実行されます。
神経伝達物質2016

1
私は、「itemgetterを使用する方が速くて簡単」という根拠のない主張に少し懐疑的でした。私は直感的に考えて、主観的ながらlambda直感的よりも単純なことなアプローチをitemgetterクラス、itemgetter 確かに速いように見えます。これがなぜなのか、私は興味があります。私の粗雑な疑いはlambdaitemgetterインスタンスがすべてのローカル変数をクロージャーコンテキストにキャプチャするという隠れたコストが発生するのに対し、インスタンスは発生しないということです。tl; dr:itemgetter速度が優先されるため、常にを使用します。
Cecil Curry

236
from operator import itemgetter
data.sort(key=itemgetter(1))

37
これは受け入れられる答えになるはずです。Charlie投稿されたタイミングも参照してください。これは、同等の関数よりも平均で126%速くitemgetterソートするクラスを示しています。lambda
Cecil Curry

9
複数のインデックスで階層的に並べ替えることもできます。例:data.sort(key=itemgetter(3,1))
Michael Ohlrogge

57

配列を高から低に並べ替える場合は、Stephenの回答に追加したいだけです。上記のコメント以外の方法は、これを行に追加することです。

reverse = True

結果は次のようになります。

data.sort(key=lambda tup: tup[1], reverse=True)

48

複数の基準、つまりタプルの2番目と3番目の要素などで並べ替えるには、

data = [(1,2,3),(1,2,1),(1,1,4)]

そして、優先順位を説明するタプルを返すラムダを定義します。例えば

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

28

スティーブンの答えは私が使うものです。完全を期すために、リスト内包表記を含むDSU(デコレートソートアンデコレート)パターンを以下に示します。

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

または、もっと簡潔に:

[b for a,b in sorted((tup[1], tup) for tup in data)]

Python Sorting HowToで述べたように、これはPython 2.4以降、主要な機能が利用可能になったときから不要です。


2
したがって、この答えはPython 2.3-に役立ちますか?あなたが少し精巧になるかもしれない最新のPythonバージョンで有効な用途はありますか?そうでない場合は、気にしないでください...ただ通り過ぎて、これを見て、古いnogginがほんの少しかき回し始めました。とにかく、これまでのPythonの時代を振り返って、乾杯と感謝を込めて。
Mechanical_meat

19

タプルのリストをソートするために(<word>, <count>)のために、count降順にしてwordアルファベット順に:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

私はこの方法を使用します:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

そしてそれは私に結果を与えます:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

1
tup [1]が文字列の場合はどうなりますか?
エリック

12

ラムダなし:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

9

itemgetter()はやや高速ですlambda tup: tup[1]が、増加は比較的控えめです(約10〜25%)。

(IPythonセッション)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

:ここでは、複数の列の逆引き数を変化させるためのitemgetter並べ替えソリューションを参照してください、あなたは、あなたの行内の複数のステップで並べ替えアレンジする必要がありますstackoverflow.com/questions/14466068/...
ローレンツ

6

@Stephenの答えは要点です!これはより良い視覚化の例です、

Ready Player Oneファンに向けて大声で叫びましょう!=)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

key比較のためにコレクションの項目を変換するために呼び出される関数ですcompareTo。Javaのようなメソッドです。

keyに渡されるパラメーターは、呼び出し可能なものでなければなりません。ここでは、を使用するとlambda、匿名関数(呼び出し可能)が作成されます。
ラムダの構文は、ラムダという単語の後に反復可能な名前が続き、その後にコードの単一のブロックが続きます。

以下の例では、特定のイベントの情報と俳優名を保持するタプルのリストをソートしています。

このリストは、イベントの発生時間(タプルの0番目の要素)でソートしています。

注- s.sort([cmp[, key[, reverse]]]) のアイテムを並べ替えます


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.