Em List of Dicts, encontre o valor min () de um campo Dict comum

94

Eu tenho uma lista de dicionários assim:

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

Quero encontrar os preços mínimo () e máximo (). Agora, posso classificar isso com bastante facilidade usando uma chave com uma expressão lambda (conforme encontrada em outro artigo do SO), então, se não houver outra maneira, não estarei preso. No entanto, pelo que tenho visto, quase sempre existe uma maneira direta em Python, então esta é uma oportunidade para eu aprender um pouco mais.

Hank Fay
fonte

Respostas:

61

Existem várias opções. Aqui está um simples:

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

[Editar]

Se você quiser iterar pela lista apenas uma vez, pode tentar isso (assumindo que os valores podem ser representados como 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
fonte
Aceito isso como a resposta, pois não só dá a resposta, mas também me mostrou que é possível abstrair sequências. Droga, Python é uma linguagem linda. Obrigado!
Hank Fay
2
Se você não precisar do seq, e a lista for grande, isso pode ser ineficiente, pois a memória de toda a lista deve ser alocada apenas para encontrar o máximo.
Charles L.
Ele jogaAttributeError: 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'])

Isso informa não apenas qual é o preço máximo, mas também qual item é mais caro.

Hugh Bothwell
fonte
4
Ah, que toque legal, devolver o item inteiro. Não é necessário neste caso, mas definitivamente é um guardião para o futuro.
Hank Fay
era isso que eu estava procurando. Impressionante. Obrigado!
svenwildermann
Uma solução elegante!
anapaulagomes
2
@ thomas.mac Você pode classificar e selecionar os 5 primeiros? consulte stackoverflow.com/questions/72899/…
hibernado
2
Isso funciona perfeitamente. Seguindo o comentário de @ thomas.mac, existe uma maneira fácil de obter todos os mínimos se houver vários (como uma lista de dicionário correspondente, por exemplo)?
Romain
44

Acho que a expressão mais direta (e mais pitônica) seria algo como:

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

Isso evita a sobrecarga de ordenar a lista - e, usando uma expressão geradora, em vez de uma compreensão de lista - na verdade evita a criação de listas também. Eficiente, direto, legível ... Pythônico!

dcrosta
fonte
9

Uma resposta seria mapear seus dictos para o valor de interesse dentro de uma expressão de gerador e, em seguida, aplicar os embutidos mine max.

myMax = max(d['price'] for d in myList)
myMin = min(d['price'] for d in myList)
Rlibby
fonte
nitpick: essas são expressões geradoras. As compreensões de lista são cercadas por [e e ], na verdade, geram uma lista Python como uma etapa intermediária.
dcrosta
@dcrosta, sim, obrigado, você está certo, é claro. Mudei o texto, pois era constrangedor.
rlibby
3

também pode usar isto:

from operator import itemgetter

lst = [{'price': 99, 'barcode': '2342355'}, {'price': 88, 'barcode': '2345566'}]  
max(map(itemgetter('price'), lst))
carton.swing
fonte