Si tengo un diccionario de Python, ¿cómo obtengo la clave de la entrada que contiene el valor mínimo?
Estaba pensando en algo que ver con la min()
función ...
Dada la entrada:
{320:1, 321:0, 322:3}
Volvería 321
.
Si tengo un diccionario de Python, ¿cómo obtengo la clave de la entrada que contiene el valor mínimo?
Estaba pensando en algo que ver con la min()
función ...
Dada la entrada:
{320:1, 321:0, 322:3}
Volvería 321
.
Respuestas:
Lo mejor: ¡ min(d, key=d.get)
no hay razón para interponer una lambda
capa de indirección inútil o extraer elementos o claves!
[11, 22, 33]
, por ejemplo , en lugar de un diccionario, por ejemplo {1: 11, 2:22, 3:33}
. 'd.get' es válido para un diccionario, pero no para una lista.
d={"a":[10, None], "b":[20, None]}
, donde el mínimo se calcula a partir de d [clave] [0]?
min()
devolver el valor en el primer valor en ordenado. clave designar la forma de ordenar los valores. key=d.get
significa que la lista se ordenará por valores del diccionario.
Aquí hay una respuesta que realmente da la solución que solicitó el OP:
>>> d = {320:1, 321:0, 322:3}
>>> d.items()
[(320, 1), (321, 0), (322, 3)]
>>> # find the minimum by comparing the second element of each tuple
>>> min(d.items(), key=lambda x: x[1])
(321, 0)
d.iteritems()
Sin embargo, el uso será más eficiente para diccionarios más grandes.
operator.itemgetter(1)
.
Para varias claves que tienen el mismo valor más bajo, puede usar una lista de comprensión:
d = {320:1, 321:0, 322:3, 323:0}
minval = min(d.values())
res = [k for k, v in d.items() if v==minval]
[321, 323]
Una versión funcional equivalente:
res = list(filter(lambda x: d[x]==minval, d))
>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k])
321
key=d.get
es mejor.
Para el caso en el que tiene varias claves mínimas y desea que sea simple
def minimums(some_dict):
positions = [] # output variable
min_value = float("inf")
for k, v in some_dict.items():
if v == min_value:
positions.append(k)
if v < min_value:
min_value = v
positions = [] # output variable
positions.append(k)
return positions
minimums({'a':1, 'b':2, 'c':-1, 'd':0, 'e':-1})
['e', 'c']
Si no está seguro de que no tiene múltiples valores mínimos, sugeriría:
d = {320:1, 321:0, 322:3, 323:0}
print ', '.join(str(key) for min_value in (min(d.values()),) for key in d if d[key]==min_value)
"""Output:
321, 323
"""
Editar: esta es una respuesta a la pregunta original del OP sobre la clave mínima, no la respuesta mínima.
Puede obtener las claves del dict usando la keys
función, y tiene razón al usar min
para encontrar el mínimo de esa lista.
Otro enfoque para abordar el problema de las claves múltiples con el mismo valor mínimo:
>>> dd = {320:1, 321:0, 322:3, 323:0}
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>>
>>> print [v for k,v in groupby(sorted((v,k) for k,v in dd.iteritems()), key=itemgetter(0)).next()[1]]
[321, 323]
Usar min
con un iterador (para uso de Python 3 en items
lugar de iteritems
); en lugar de lambda, use el itemgetter
operador from, que es más rápido que lambda.
from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))
d={}
d[320]=1
d[321]=0
d[322]=3
value = min(d.values())
for k in d.keys():
if d[k] == value:
print k,d[k]
Comparé cómo funcionan las siguientes tres opciones:
import random, datetime
myDict = {}
for i in range( 10000000 ):
myDict[ i ] = random.randint( 0, 10000000 )
# OPTION 1
start = datetime.datetime.now()
sorted = []
for i in myDict:
sorted.append( ( i, myDict[ i ] ) )
sorted.sort( key = lambda x: x[1] )
print( sorted[0][0] )
end = datetime.datetime.now()
print( end - start )
# OPTION 2
start = datetime.datetime.now()
myDict_values = list( myDict.values() )
myDict_keys = list( myDict.keys() )
min_value = min( myDict_values )
print( myDict_keys[ myDict_values.index( min_value ) ] )
end = datetime.datetime.now()
print( end - start )
# OPTION 3
start = datetime.datetime.now()
print( min( myDict, key=myDict.get ) )
end = datetime.datetime.now()
print( end - start )
Salida de muestra:
#option 1
236230
0:00:14.136808
#option 2
236230
0:00:00.458026
#option 3
236230
0:00:00.824048
Para crear una clase ordenable, debe anular 6 funciones especiales, para que la función min () la llame
estos métodos están __lt__ , __le__, __gt__, __ge__, __eq__ , __ne__
en orden para que sean menores que, menores que o iguales, mayores que, mayores que o iguales, iguales, no iguales. por ejemplo, debe implementar __lt__
lo siguiente:
def __lt__(self, other):
return self.comparable_value < other.comparable_value
entonces puede usar la función min de la siguiente manera:
minValue = min(yourList, key=(lambda k: yourList[k]))
Esto funcionó para mí.
min(zip(d.values(), d.keys()))[1]
Use la función zip para crear un iterador de tuplas que contengan valores y claves. Luego envuélvala con una función min que tome el mínimo basado en la primera tecla. Esto devuelve una tupla que contiene un par (valor, clave). El índice de [1] se usa para obtener la clave correspondiente
# python
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
321
min()
).
¿Es esto lo que estás buscando?
d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'
print d[min(d.keys())]
Imprime 'catorce'