Pythonは、辞書リストを1つまたは複数のフィールドでソートします.
5806 ワード
目次 1. 前言 2. Lambda式 3. itemgetter関数 4. パフォーマンステスト 1.はじめに
ソートといえばsorted()関数を使用し、keyキーワードパラメータを使用してソートのルールをカスタマイズすることができます.次に、データベースからクエリーしたWebサイトの会員情報のリストを仮定します.
ソートを実現する2つの方法、lambdaとitemgetter()を以下に示すが、itemgetter()方式を使用すると少し速く動作するので、性能に対する要求が高い場合はitemgetter()方式を使用することについて事前に説明する.
2.lambda式
sorted()関数は、lambda式と組み合わせて、指定した辞書リストフィールドのソートを実現します.
実行結果:
3.itemgetter関数
operatorモジュールのitemgetter関数を使用すると、私たちのsorted()関数は、少なくともlambdaよりも簡単に辞書リストフィールドのソートを容易に実現することができます.
実行結果:
itemgetter()関数は、次のコードなど、複数のkeysもサポートします.
実行結果:
rowsは、1つのキーワードパラメータ(key=xx)のみを受け入れるsorted()内蔵関数に渡されます.このパラメータはcallableタイプであり、rowsから1つの要素を受け入れ、ソートに使用される値を返します.itemgetter()関数は、このcallableオブジェクトの作成を担当します.
4.性能テスト
私はちょうど上でitemgetter()の性能がもっと良いことに言及したばかりで、それでは同級生が聞きますか?どうして知ってるの?次のパフォーマンステストを見て結果がわかります.
lambdaが実行するステップはitemgetterよりずっと多く、itemgetterの性能が優れていることが明らかになった.
ソートといえばsorted()関数を使用し、keyキーワードパラメータを使用してソートのルールをカスタマイズすることができます.次に、データベースからクエリーしたWebサイトの会員情報のリストを仮定します.
rows = [
{'name': 'Jack', 'uid': 1003, 'level': 5},
{'name': 'Gigi', 'uid': 1001, 'level': 2},
{'name': 'Koko', 'uid': 1005, 'level': 3},
{'name': 'Eric', 'uid': 1004, 'level': 2},
{'name': 'Aven', 'uid': 1002, 'level': 6}
]
ソートを実現する2つの方法、lambdaとitemgetter()を以下に示すが、itemgetter()方式を使用すると少し速く動作するので、性能に対する要求が高い場合はitemgetter()方式を使用することについて事前に説明する.
2.lambda式
sorted()関数は、lambda式と組み合わせて、指定した辞書リストフィールドのソートを実現します.
# name
rows_by_name = sorted(rows, key=lambda r: r['name'])
# uid
rows_by_uid = sorted(rows, key=lambda r: r['uid'])
print(rows_by_name)
print(rows_by_uid)
実行結果:
[{'name': 'Aven', 'uid': 1002, 'level': 6}, {'name': 'Eric', 'uid': 1004, 'level': 2}, {'name': 'Gigi', 'uid': 1001, 'level': 2}, {'name': 'Jack', 'uid': 1003, 'level': 5}, {'name': 'Koko', 'uid': 1005, 'level': 3}]
[{'name': 'Gigi', 'uid': 1001, 'level': 2}, {'name': 'Aven', 'uid': 1002, 'level': 6}, {'name': 'Jack', 'uid': 1003, 'level': 5}, {'name': 'Eric', 'uid': 1004, 'level': 2}, {'name': 'Koko', 'uid': 1005, 'level': 3}]
3.itemgetter関数
operatorモジュールのitemgetter関数を使用すると、私たちのsorted()関数は、少なくともlambdaよりも簡単に辞書リストフィールドのソートを容易に実現することができます.
from operator import itemgetter
rows_by_name = sorted(rows, key=itemgetter('name'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_name)
print(rows_by_uid)
実行結果:
[{'name': 'Aven', 'uid': 1002, 'level': 6}, {'name': 'Eric', 'uid': 1004, 'level': 2}, {'name': 'Gigi', 'uid': 1001, 'level': 2}, {'name': 'Jack', 'uid': 1003, 'level': 5}, {'name': 'Koko', 'uid': 1005, 'level': 3}]
[{'name': 'Gigi', 'uid': 1001, 'level': 2}, {'name': 'Aven', 'uid': 1002, 'level': 6}, {'name': 'Jack', 'uid': 1003, 'level': 5}, {'name': 'Eric', 'uid': 1004, 'level': 2}, {'name': 'Koko', 'uid': 1005, 'level': 3}]
itemgetter()関数は、次のコードなど、複数のkeysもサポートします.
rows_by_lname = sorted(rows, key=itemgetter('name','level'))
print(rows_by_uname)
実行結果:
[{'name': 'Aven', 'uid': 1002, 'level': 6}, {'name': 'Eric', 'uid': 1004, 'level': 2}, {'name': 'Gigi', 'uid': 1001, 'level': 2}, {'name': 'Jack', 'uid': 1003, 'level': 5}, {'name': 'Koko', 'uid': 1005, 'level': 3}]
rowsは、1つのキーワードパラメータ(key=xx)のみを受け入れるsorted()内蔵関数に渡されます.このパラメータはcallableタイプであり、rowsから1つの要素を受け入れ、ソートに使用される値を返します.itemgetter()関数は、このcallableオブジェクトの作成を担当します.
4.性能テスト
私はちょうど上でitemgetter()の性能がもっと良いことに言及したばかりで、それでは同級生が聞きますか?どうして知ってるの?次のパフォーマンステストを見て結果がわかります.
>>> import dis
>>> rows = [
... {'name': 'Jack', 'uid': 1003, 'level': 5},
... {'name': 'Gigi', 'uid': 1001, 'level': 2},
... {'name': 'Koko', 'uid': 1005, 'level': 3},
... {'name': 'Eric', 'uid': 1004, 'level': 2},
... {'name': 'Aven', 'uid': 1002, 'level': 6}
... ]
# lambda
>>> x = lambda: sorted(rows, key=lambda r: r['name'])
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (sorted)
2 LOAD_GLOBAL 1 (rows)
4 LOAD_CONST 1 ( at 0x1047cb920, file "", line 1>)
6 LOAD_CONST 2 ('..')
8 MAKE_FUNCTION 0
10 LOAD_CONST 3 (('key',))
12 CALL_FUNCTION_KW 2
14 RETURN_VALUE
Disassembly of at 0x1047cb920, file "", line 1>:
1 0 LOAD_FAST 0 (r)
2 LOAD_CONST 1 ('name')
4 BINARY_SUBSCR
6 RETURN_VALUE
# itemgetter
>>> from operator import itemgetter
>>> y = lambda: sorted(rows, key=itemgetter('name'))
>>> dis.dis(y)
1 0 LOAD_GLOBAL 0 (sorted)
2 LOAD_GLOBAL 1 (rows)
4 LOAD_GLOBAL 2 (itemgetter)
6 LOAD_CONST 1 ('name')
8 CALL_FUNCTION 1
10 LOAD_CONST 2 (('key',))
12 CALL_FUNCTION_KW 2
14 RETURN_VALUE
lambdaが実行するステップはitemgetterよりずっと多く、itemgetterの性能が優れていることが明らかになった.