Si j'ai un dictionnaire Python, comment puis-je obtenir la clé de l'entrée qui contient la valeur minimale?
Je pensais à quelque chose à voir avec la min()
fonction ...
Compte tenu de l'entrée:
{320:1, 321:0, 322:3}
Cela reviendrait 321
.
Si j'ai un dictionnaire Python, comment puis-je obtenir la clé de l'entrée qui contient la valeur minimale?
Je pensais à quelque chose à voir avec la min()
fonction ...
Compte tenu de l'entrée:
{320:1, 321:0, 322:3}
Cela reviendrait 321
.
Réponses:
Le meilleur: min(d, key=d.get)
- aucune raison d'interposer une lambda
couche d'indirection inutile ou d'extraire des éléments ou des clés!
[11, 22, 33]
, au lieu d'un dictionnaire par exemple {1: 11, 2:22, 3:33}
. 'd.get' est valide pour un dictionnaire, mais pas pour une liste.
d={"a":[10, None], "b":[20, None]}
où le min est calculé à partir de d [clé] [0]?
min()
renvoie la valeur de la première valeur dans trié. clé désigne la façon de trier les valeurs. key=d.get
signifie que la liste sera triée selon les valeurs du dictionnaire.
Voici une réponse qui donne réellement la solution demandée par l'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()
Cependant, l' utilisation sera plus efficace pour les dictionnaires plus volumineux.
operator.itemgetter(1)
.
Pour plusieurs clés qui ont la valeur la plus basse égale, vous pouvez utiliser une compréhension de liste:
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]
Une version fonctionnelle équivalente:
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
c'est mieux.
Dans le cas où vous avez plusieurs clés minimales et que vous souhaitez rester 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 vous n'êtes pas sûr de ne pas avoir plusieurs valeurs minimales, je suggère:
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
"""
Edit: c'est une réponse à la question originale de l'OP sur la clé minimale, pas la réponse minimale.
Vous pouvez obtenir les clés du dict en utilisant la keys
fonction, et vous avez raison d'utiliser min
pour trouver le minimum de cette liste.
Une autre approche pour résoudre le problème de plusieurs clés avec la même valeur min:
>>> 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]
Utiliser min
avec un itérateur (pour python 3 utiliser items
au lieu de iteritems
); au lieu de lambda, utilisez l' itemgetter
opérateur from, qui est plus rapide 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]
J'ai comparé les performances des trois options suivantes:
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 )
Exemple de sortie:
#option 1
236230
0:00:14.136808
#option 2
236230
0:00:00.458026
#option 3
236230
0:00:00.824048
pour créer une classe ordonnée, vous devez remplacer 6 fonctions spéciales, afin qu'elle soit appelée par la fonction min ()
ces méthodes sont __lt__ , __le__, __gt__, __ge__, __eq__ , __ne__
dans l'ordre où elles sont inférieures, inférieures ou égales, supérieures à, supérieures ou égales, égales, non égales. par exemple, vous devez implémenter __lt__
comme suit:
def __lt__(self, other):
return self.comparable_value < other.comparable_value
alors vous pouvez utiliser la fonction min comme suit:
minValue = min(yourList, key=(lambda k: yourList[k]))
cela a fonctionné pour moi.
min(zip(d.values(), d.keys()))[1]
Utilisez la fonction zip pour créer un itérateur de tuples contenant des valeurs et des clés. Enveloppez-le ensuite avec une fonction min qui prend le minimum en fonction de la première clé. Cela renvoie un tuple contenant une paire (valeur, clé). L'index de [1] est utilisé pour obtenir la clé correspondante
# python
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
321
min()
).
Est-ce ce que vous recherchez?
d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'
print d[min(d.keys())]
Imprime «quatorze»