Étant donné une liste plate de dictionnaires simples
lst = [{'key1': 1}, {'key2': 2}, {'key3': 3}]
Je voudrais trouver le dict qui donne la valeur minimale évaluée en utilisant une méthode non détaillée ici. Ma première idée a été d'itérer la liste pour vérifier dict par dict, mais cela échoue:
for k, v in [x.items() for x in lst]:
print(k, v)
résultats ValueError (ainsi qu'en utilisant un générateur au lieu de la liste):
for k, v in [x.items() for x in lst]:
ValueError: not enough values to unpack (expected 2, got 1)
Cependant,
for x in lst:
for k, v in x.items():
print(k, v)
les rendements
key1 1
key2 2
key3 3
Comme prévu. Je suppose que toutes les approches fonctionnent comme prévu (sauf PEBKAC), mais pourquoi cela ne fonctionne-t-il pas en utilisant la compréhension de la liste? Quelqu'un pourrait-il m'éclairer?
Edit: j'utilise python 3 et je sais que items () donne un dict_view mais je ne vois pas pourquoi la logique ne fonctionne pas.
Vous manquez un niveau d'itération.
Normalement, les dict ont plus d'une paire clé/valeur. dict.items()
convertit le dictionnaire entier en une séquence de tuples sous la forme (key, value)
. Dans votre cas, chaque dictionnaire a un seul élément, mais le résultat de items()
est toujours un Tuple de tuples.
Si vous imprimez le résultat de [x.items() for x in lst]
vous verrez que le résultat est une liste d'éléments dict_view
; chacun de ceux-ci peut lui-même être itéré.
Au lieu de prendre le premier élément de votre dict_view
vous pouvez ajouter un niveau d'indentation (comme l'a suggéré @DanielRoseman) dans votre compréhension de liste:
for k, v in [(k, v) for x in lst for (k, v) in x.items()]:
print(k, v)
rendement
key1 1
key2 2
key3 3
comme prévu.
Essayez de décompresser votre lst
étape par étape pour comprendre comment il est construit.
>>> in: lst[0].items()
>>> out: [('key1', 1)]
Votre résultat (qui est égal à votre expression x.items()
dans la compréhension de la liste) est ne autre liste contenant votre Tuple de k et v. Le Tuple est l'élément d'index 0 dans cette liste (et aussi le seul élément du tout). Vous devez donc aller comme
for k, v in [x.items()[0] for x in lst]:
print(k, v)
Vous pouvez parcourir la paire clé/valeur d'un dictionnaire comme ceci: -
for k, v in dic.items():
print(k, v)
ce que le code ci-dessus fait est de convertir d'abord le dictionnaire en une liste de tuples qui sont ensuite décompressés un par un tout en itérant en k, v comme: -
k, v = (k, v) # Tuple unpacking.
Maintenant, dans votre cas, considérez ce code: -
z = [x.items() for x in lst]
print(z)
La sortie est
[dict_items([('key1', 1)]), dict_items([('key2', 2)]), dict_items([('key3', 3)])]
soit un liste de listes de Tuple.
Alors, réécrivons votre code comme: -
for k, v in z:
print(k, v)
Où z est une liste de listes de Tuple. A chaque itération, il récupère une liste (qui ne contient qu'un seul élément) dans la liste parent puis il essaie: -
k, v = [(key, value)] # a list of only one Tuple to be unpacked against two variables and hence the failure.
J'espère que cela a été utile.