In List of Dicts, trova il valore min () di un campo Dict comune


94

Ho un elenco di dizionari in questo modo:

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

Voglio trovare i prezzi min () e max (). Ora, posso ordinarlo abbastanza facilmente usando una chiave con un'espressione lambda (come si trova in un altro articolo SO), quindi se non c'è altro modo non sono bloccato. Tuttavia, da quello che ho visto c'è quasi sempre un modo diretto in Python, quindi questa è un'opportunità per me per imparare un po 'di più.

Risposte:


61

Ci sono diverse opzioni. Eccone uno semplice:

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

[Modificare]

Se desideri scorrere l'elenco una sola volta, puoi provare questo (assumendo che i valori possano essere rappresentati come 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)

Accetto questa come la risposta in quanto non solo fornisce la risposta, ma mi ha anche mostrato che si possono astrarre sequenze. Maledizione, Python è un bel linguaggio. Grazie!
Hank Fay

2
Se non hai bisogno di seq, e l'elenco è grande, questo può essere inefficiente poiché la memoria per l'intero elenco deve essere allocata solo per trovare il max.
Charles L.

LanciaAttributeError: module 'sys' has no attribute 'maxint'
Suncatcher

241
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'])

Questo ti dice non solo qual è il prezzo massimo, ma anche quale articolo è più costoso.


4
Ah, è un bel tocco, restituire l'intero articolo. Non necessario in questo caso, ma decisamente un custode per il futuro.
Hank Fay

questo è quello che stavo cercando. Eccezionale. Grazie!
svenwildermann

Una soluzione elegante!
anapaulagomes

2
@ thomas.mac Potresti ordinare e quindi selezionare i primi 5? vedi stackoverflow.com/questions/72899/...
hibernado

2
Funziona perfettamente. Dopo il commento di @ thomas.mac, c'è un modo semplice per ottenere tutti i minimi se ce ne sono diversi (come un elenco di dict corrispondenti, ad esempio)?
Romain

44

Penso che l'espressione più diretta (e più pitonica) sarebbe qualcosa del tipo:

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

Ciò evita il sovraccarico dell'ordinamento dell'elenco e, utilizzando un'espressione del generatore, invece di una comprensione dell'elenco, evita anche di creare elenchi. Efficiente, diretto, leggibile ... Pythonic!


9

Una risposta sarebbe mappare i tuoi dettami sul valore di interesse all'interno di un'espressione del generatore e quindi applicare i built-in mine max.

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

nitpick: quelle sono espressioni generatrici. Le comprensioni della lista sono circondate da [e ]e in realtà generano un elenco Python come passaggio intermedio.
dcrosta

@dcrosta, si, grazie, hai ragione ovviamente. Ho cambiato la formulazione poiché era imbarazzante.
rlibby

3

può anche usare questo:

from operator import itemgetter

lst = [{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]  
max(map(itemgetter('price'), lst))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.