Na liście List of Dicts znajdź min () wartość wspólnego pola Dict

91

Mam listę takich słowników:

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

Chcę znaleźć ceny minimalne () i maksymalne (). Teraz mogę to łatwo posortować za pomocą klucza z wyrażeniem lambda (jak można znaleźć w innym artykule SO), więc jeśli nie ma innego sposobu, nie utknąłem. Jednak z tego, co widziałem, w Pythonie prawie zawsze jest bezpośrednia droga, więc jest to dla mnie okazja, aby dowiedzieć się trochę więcej.

Hank Fay
źródło

Odpowiedzi:

60

Istnieje kilka opcji. Oto prosty przykład:

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

[Edytować]

Jeśli chcesz tylko raz powtórzyć listę, możesz spróbować tego (zakładając, że wartości mogą być reprezentowane jako 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)
dappawit
źródło
Przyjmuję to jako odpowiedź, ponieważ nie tylko daje odpowiedź, ale także pokazało mi, że można abstrakcyjne sekwencje. Cholera, Python to piękny język. Dzięki!
Hank Fay,
2
Jeśli nie potrzebujesz seq, a lista jest duża, może to być nieefektywne, ponieważ pamięć dla całej listy musi zostać przydzielona tylko po to, aby znaleźć maks.
Charles L.
RzucaAttributeError: 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'])

Dzięki temu dowiesz się nie tylko, jaka jest maksymalna cena, ale także, który przedmiot jest najdroższy.

Hugh Bothwell
źródło
4
Ach, to miły akcent, zwrócenie całego przedmiotu. Nie jest to potrzebne w tym przypadku, ale zdecydowanie jest opiekunem na przyszłość.
Hank Fay,
tego właśnie szukałem. Niesamowite. Dzięki!
svenwildermann
Eleganckie rozwiązanie!
anapaulagomes
2
@ thomas.mac Możesz posortować, a następnie wybrać 5 najlepszych? zobacz stackoverflow.com/questions/72899/…
hibernado
2
To działa doskonale. Czy po komentarzu @ thomas.mac istnieje łatwy sposób na uzyskanie wszystkich minimów, jeśli jest ich kilka (na przykład lista pasujących dykt)?
Romain
40

Myślę, że najbardziej bezpośrednim (i najbardziej Pythonowym) wyrażeniem byłoby coś takiego:

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

Dzięki temu unika się narzutu związanego z sortowaniem listy - i używając wyrażenia generatora zamiast wyrażenia listy - w rzeczywistości unika się również tworzenia jakichkolwiek list. Wydajne, bezpośrednie, czytelne ... Pythonic!

dcrosta
źródło
8

Jedną z odpowiedzi byłoby odwzorowanie twoich dykt na interesującą wartość wewnątrz wyrażenia generatora, a następnie zastosowanie wbudowanych funkcji mini max.

myMax = max(d['price'] for d in myList)
myMin = min(d['price'] for d in myList)
rlibby
źródło
czubek: to są wyrażenia generatora. Listy składane są otoczone znakami [i ], i faktycznie generują listę Pythona jako krok pośredni.
dcrosta
@dcrosta, tak, dziękuję, masz oczywiście rację. Zmieniłem sformułowanie, ponieważ było to żenujące.
rlibby
3

można również użyć tego:

from operator import itemgetter

lst = [{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]  
max(map(itemgetter('price'), lst))
karton. huśtawka
źródło