operator.itemgetter を使用して辞書をソートする 質問する

operator.itemgetter を使用して辞書をソートする 質問する

SOで質問がありました数分前に、値に基づいて辞書のキーをソートする方法について説明しました。

数日前にソートの方法について読みoperator.itemgetter、試してみることにしましたが、うまくいかないようです。

質問に対する回答に問題があるわけではなく、単にこれを で試してみたかっただけですoperator.itemgetter

辞書は次のようになりました:

>>> mydict = { 'a1': ['g',6],
           'a2': ['e',2],
           'a3': ['h',3],
           'a4': ['s',2],
           'a5': ['j',9],
           'a6': ['y',7] }

私はこれを試しました:

>>> l = sorted(mydict.itervalues(), key=operator.itemgetter(1))
>>> l
[['e', 2], ['s', 2], ['h', 3], ['g', 6], ['y', 7], ['j', 9]]

これは期待通りに動作します。ただし、完全な辞書 ( ) がないのでmydict.itervalues()、これを試しました:

>>> complete = sorted(mydict.iteritems(), key=operator.itemgetter(2))

これは機能しません(期待どおりには機能しません)。

では、ネストされたキーと値のペアを使用して辞書をソートしoperator.itemgetter、呼び出すにはどうすればよいでしょうか。itemgetter

ベストアンサー1

In [6]: sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v))
Out[6]: 
[('a2', ['e', 2]),
 ('a4', ['s', 2]),
 ('a3', ['h', 3]),
 ('a1', ['g', 6]),
 ('a6', ['y', 7]),
 ('a5', ['j', 9])]

mydict.iteritems()キーパラメータは常に、反復可能オブジェクト( )から一度に1つの項目が供給される関数です。この場合、項目は次のようになります。

('a2',['e',2])

('a2',['e',2])したがって、入力として受け取り、2 を返す関数が必要です。

lambda (k,v): ...kは、1 つの引数 (2 要素のタプル) を受け取り、それをとに展開する匿名関数ですv。したがって、lambda関数をアイテムに適用すると、kは になり'a2'vは になります['e',2]

lambda (k,v): operator.itemgetter(1)(v)を項目に適用すると が返されoperator.itemgetter(1)(['e',2])、 の 2 番目の項目['e',2]、つまり 2 が「itemgets」されます。

lambda (k,v): operator.itemgetter(1)(v)Pythonでコーディングする良い方法ではないことに注意してください。gnibblerが指摘しているように、operator.itemgetter(1)は再計算されます各項目について。これは非効率的です。 を使用する目的operator.itemgetter(1)は、何度も適用できる関数を作成することです。 関数を毎回再作成する必要はありません。 の方がlambda (k,v): v[1]読みやすく、高速です。

In [15]: %timeit sorted(mydict.iteritems(), key=lambda (k,v): v[1])
100000 loops, best of 3: 7.55 us per loop

In [16]: %timeit sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v))
100000 loops, best of 3: 11.2 us per loop

おすすめ記事