web-dev-qa-db-ja.com

python-辞書のリストの繰り返しと展開

単純な辞書のフラットリストがある場合

lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]

ここに詳述されていない方法を使用して評価された最小値をもたらす辞書を見つけたいです。私の最初のアイデアはリストを反復してdictごとにdictをチェックすることでしたが、これは失敗します:

for k, v in [x.items() for x in lst]:
    print(k, v)

結果ValueError(およびリストの代わりにジェネレーターを使用):

for k, v in [x.items() for x in lst]:
ValueError: not enough values to unpack (expected 2, got 1)

しかしながら、

for x in lst:
    for k, v in x.items():
        print(k, v)

利回り

key1 1
key2 2
key3 3

予想通り。 (PEBKACを除いて)すべてのアプローチが意図したとおりに機能すると仮定しますが、なぜリスト内包表記を使用しても機能しないのですか?誰かが私を啓発できますか?

編集:python 3を使用し、items()がdict_viewを生成することを知っていますが、ロジックが機能しない理由がわかりません。

13
jake77

反復のレベルが欠落しています。

通常、dictには複数のキー/値のペアがあります。 dict.items()は、辞書全体を_(key, value)_の形式のタプルのシーケンスに変換します。あなたの場合、各ディクショナリにはアイテムが1つしかありませんが、items()の結果はまだタプルのタプルです。

[x.items() for x in lst]の結果を印刷すると、結果が_dict_view_アイテムのリストであることがわかります。それらのそれぞれを反復することができます。

7
Daniel Roseman

dict_viewの最初の要素を取得する代わりに、リスト内包表記に1レベルのインデントを追加できます(@DanielRosemanが提案したとおり)。

for k, v in [(k, v) for x in lst for (k, v) in x.items()]:
  print(k, v)

産出

key1 1
key2 2
key3 3

予想通り。

4
Kruupös

lstを段階的に解凍して、構成方法を理解してください。

_>>> in: lst[0].items()
>>> out: [('key1', 1)]
_

結果(リスト内包表記のx.items()式と等しい)は、kとvのタプルを含む別のリストです。タプルは、このリストのインデックス0の要素です(また、唯一の要素)。だからあなたは次のように行く必要があります

_for k, v in [x.items()[0] for x in lst]:
    print(k, v)
_
1
offeltoffel

次のような辞書のキーと値のペアを反復処理できます。

for k, v in dic.items():
    print(k, v)

上記のコードが行うことは、最初に辞書をタプルのリストに変換し、それを次のようにk、vに反復しながら1つずつ展開します:

k, v = (k, v) # Tuple unpacking.

今あなたの場合、このコードを考慮してください:-

z = [x.items() for x in lst]
print(z)

出力は

[dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])] 

つまり、タプルのリストのlistです。

それでは、コードを次のように書き換えましょう。

for k, v in z:
    print(k, v)

ここで、zはTupleのリストのリストです。各反復で、親リストからリスト(要素を1つだけ含む)を選択し、次に試行します。

k, v = [(key, value)] # a list of only one Tuple to be unpacked against two variables and hence the failure.

これがお役に立てば幸いです。

0
gautamaggarwal