63

リストを最初に値でソートし、次に 2 番目の値でソートしたいと考えています。これを行う簡単な方法はありますか?以下に小さな例を示します。

A = [{'name':'john','age':45},
     {'name':'andi','age':23},
     {'name':'john','age':22},
     {'name':'paul','age':35},
     {'name':'john','age':21}]

このコマンドは、このリストを次の基準でソートするためのもの'name'です:

sorted(A, key = lambda user: user['name'])

しかし、このリストを 2 番目の値で並べ替えるにはどうすればよいでしょうか? 'age'この例のように。

このような並べ替えが必要です(最初に並べ替えて'name'から並べ替えます'age'):

andi - 23
john - 21
john - 22
john - 45
paul - 35

ありがとう!

4

3 に答える 3

91
>>> A = [{'name':'john','age':45},
     {'name':'andi','age':23},
     {'name':'john','age':22},
     {'name':'paul','age':35},
     {'name':'john','age':21}]
>>> sorted(A, key = lambda user: (user['name'], user['age']))
[{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}]

これは 2 つの属性のタプルでソートします。以下は同等であり、はるかに高速でクリーンです。

>>> from operator import itemgetter
>>> sorted(A, key=itemgetter('name', 'age'))
[{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}]

コメントから: @Bakuriu

2 つの間に大きな違いはないと思いますが、1 つの opcode( )itemgetterの間にキーを抽出して作成するため、オーバーヘッドを少し回避できます。他のバイトコード) 最後に添え字 ( ) を呼び出し、 を構築して返す...これは、インタープリターにとってより多くの作業です。tupleCALL_FUNCTIONlambdaBINARY_SUBSCRtuple

要約するitemgetterと、実行を完全にCレベルに保つため、可能な限り高速になります。

于 2013-04-18T12:28:26.887 に答える
53
from operator import itemgetter

sorted(your_list, key=itemgetter('name', 'age'))
于 2013-04-18T12:28:35.633 に答える
0

代替の一般的な解決策は次のとおりです。キーと値で dict の要素をソートします。その利点 - キーを指定する必要がなく、一部の辞書で一部のキーが欠落している場合でも機能します。

def sort_key_func(item):
    """ helper function used to sort list of dicts

    :param item: dict
    :return: sorted list of tuples (k, v)
    """
    pairs = []
    for k, v in item.items():
        pairs.append((k, v))
    return sorted(pairs)
于 2015-01-22T17:19:49.013 に答える