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.

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)

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.


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!


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)

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))
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.