Dans List of Dicts, recherchez la valeur min () d'un champ Dict commun


91

J'ai une liste de dictionnaires comme ceci:

[{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]

Je veux trouver les prix min () et max (). Maintenant, je peux trier cela assez facilement en utilisant une clé avec une expression lambda (comme trouvé dans un autre article SO), donc s'il n'y a pas d'autre moyen, je ne suis pas coincé. Cependant, d'après ce que j'ai vu, il y a presque toujours un moyen direct en Python, c'est donc l'occasion pour moi d'en apprendre un peu plus.

Réponses:


60

Il existe plusieurs options. En voici une simple:

seq = [x['the_key'] for x in dict_list]
min(seq)
max(seq)

[Éditer]

Si vous ne souhaitez parcourir la liste qu'une seule fois, vous pouvez essayer ceci (en supposant que les valeurs puissent être représentées par ints):

import sys

lo,hi = sys.maxint,-sys.maxint-1
for x in (item['the_key'] for item in dict_list):
    lo,hi = min(x,lo),max(x,hi)

J'accepte cela comme la réponse car non seulement cela donne la réponse, mais cela m'a aussi montré que l'on peut abstraire des séquences. Darn, Python est un beau langage. Merci!
Hank Fay

2
Si vous n'avez pas besoin de seq, et que la liste est grande, cela peut être inefficace car la mémoire de la liste entière doit être allouée uniquement pour trouver le maximum.
Charles L.

Il jetteAttributeError: module 'sys' has no attribute 'maxint'
Suncatcher

229
lst = [{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]

maxPricedItem = max(lst, key=lambda x:x['price'])
minPricedItem = min(lst, key=lambda x:x['price'])

Cela vous indique non seulement quel est le prix maximum, mais également quel article est le plus cher.


4
Ah, c'est une bonne idée de retourner l'article entier. Pas nécessaire dans ce cas, mais très certainement un gardien pour l'avenir.
Hank Fay

c'est ce que je cherchais. Impressionnant. Merci!
svenwildermann

Une solution élégante!
anapaulagomes

2
@ thomas.mac Vous pouvez trier puis sélectionner le top 5? voir stackoverflow.com/questions/72899/…
hibernado

2
Cela fonctionne parfaitement. Suite au commentaire de @ thomas.mac, y a-t-il un moyen simple d'obtenir tous les minima s'il y en a plusieurs (comme une liste de dict correspondants, par exemple)?
Romain le

40

Je pense que l'expression la plus directe (et la plus pythonique) serait quelque chose comme:

min_price = min(item['price'] for item in items)

Cela évite la surcharge de tri de la liste - et, en utilisant une expression de générateur, au lieu d'une compréhension de liste - évite également de créer des listes. Efficace, direct, lisible ... Pythonique!


8

Une réponse serait de mapper vos dictats sur la valeur d'intérêt dans une expression de générateur, puis d'appliquer les éléments intégrés minet max.

myMax = max(d['price'] for d in myList)
myMin = min(d['price'] for d in myList)

nitpick: ce sont des expressions génératrices. Les compréhensions de liste sont entourées de [et ]et génèrent en fait une liste Python comme étape intermédiaire.
dcrosta

@dcrosta, oui, merci, vous avez raison bien sûr. J'ai changé le libellé car c'était embarrassant.
rlibby

3

peut également utiliser ceci:

from operator import itemgetter

lst = [{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]  
max(map(itemgetter('price'), lst))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.