Faute de frappe dans votre déclaration de retour? Sinon, pourquoi 321? Cela ne devrait-il pas être 320?
GreenMatt
3
@myself: D'accord, maintenant je vois - ce que l'on veut, c'est la clé de l'entrée où la valeur de l'entrée est le minimum. Une meilleure formulation de la question s'il vous plaît, car d'autres ont évidemment pensé la même chose que moi.
GreenMatt
2
Journée de sensibilisation à la structure des données: si vous interrogez (ou supprimez) uniquement l'élément minimal, envisagez d'utiliser une file d'attente ou un segment de priorité.
Colonel Panic
Réponses:
597
Le meilleur: min(d, key=d.get)- aucune raison d'interposer une lambdacouche d'indirection inutile ou d'extraire des éléments ou des clés!
@ KarelBílek cela signifie que vous avez passé en "d" une liste par exemple [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.
ToolmakerSteve
9
que faire si deux clés différentes ont la même valeur? et ils se trouvent être à la fois la plus petite valeur? comment pouvez-vous faire revenir les deux?
user3226932
5
Cette technique peut-elle être utilisée si les valeurs dict sont des listes, ex:, d={"a":[10, None], "b":[20, None]}où le min est calculé à partir de d [clé] [0]?
TrakJohnson
4
Comment cela marche-t-il? Quel genre de fonction min est que, je pensais que min () ne prenait que des valeurs individuelles ou des listes comme arguments. Comment fonctionne-t-il en boucle sur toutes les entrées du dictionnaire?
azureai
2
min()renvoie la valeur de la première valeur dans trié. clé désigne la façon de trier les valeurs. key=d.getsignifie que la liste sera triée selon les valeurs du dictionnaire.
notilas
45
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.
Votre réponse est très utile et d'autres sont probablement d'accord: voir les multiples commentaires d'ailleurs dans la réponse acceptée. Cependant, je devais revenir deux fois pour le trouver: envisageriez-vous de proposer une modification de la réponse acceptée? Le vôtre est en fait complémentaire.
Ne méritant pas vraiment un downvote, car la question originale de l'affiche n'était pas aussi claire qu'elle aurait pu l'être.
GreenMatt
@ Space_C0wb0y: peut-être pouvez-vous être si gentil de remarquer que le PO a modifié sa question pour signifier quelque chose de différent, après avoir répondu
Eli Bendersky
3
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 minavec un itérateur (pour python 3 utiliser itemsau lieu de iteritems); au lieu de lambda, utilisez l' itemgetteropérateur from, qui est plus rapide que lambda.
from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))
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:
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
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
β.εηοιτ.βε
@ β.εηοιτ.βε que mieux?
rajn
-1
# python
d={320:1,321:0,322:3}
reduce(lambda x,y: x if d[x]<=d[y]else y, d.iterkeys())321
1) Réduire est généralement plus lent que itertools. 2) La plupart des implémentations de réduire peuvent être faites plus simplement avec n'importe laquelle ou toutes. 3) Je suis un porte-parole géant pour le GvR. 4) Le module opérateur rend inutiles la plupart des lambdas simples, et les lambdas complexes doivent de toute façon être définis comme des fonctions réelles. J'ai peut-être juste peur de la programmation fonctionnelle. ;)
MikeD
@miked: dites m'en plus. qu'est-ce que gvr et quel est le module opérateur? pourriez-vous publier des liens? j'en connais peut-être d'autres, mais je ne suis qu'un intermédiaire en python. prêt à apprendre! :-)
eruciform
GvR est Guido van Rossum, le dictateur bienveillant de Python pour la vie. Voici un article de cinq ans de lui expliquant pourquoi les lisp-ismes (carte, filtre, réduction, lambda) n'ont pas beaucoup de place en python à l'avenir, et ces raisons sont toujours valables aujourd'hui. Le module opérateur a des remplacements pour extraire les membres : "lambda x: x [1]" par rapport à "itemgetter (1)" est un caractère plus long et prend sans doute plus de temps à comprendre. Je n'ai plus d'espace, mais posez des questions!
Réponses:
Le meilleur:
min(d, key=d.get)
- aucune raison d'interposer unelambda
couche d'indirection inutile ou d'extraire des éléments ou des clés!la source
[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.iteritems()
Cependant, l' utilisation sera plus efficace pour les dictionnaires plus volumineux.la source
operator.itemgetter(1)
.Pour plusieurs clés qui ont la valeur la plus basse égale, vous pouvez utiliser une compréhension de liste:
Une version fonctionnelle équivalente:
la source
min(d.items(), key=lambda x: x[1])[0]
la source
la source
key=d.get
c'est mieux.Dans le cas où vous avez plusieurs clés minimales et que vous souhaitez rester simple
la source
Si vous n'êtes pas sûr de ne pas avoir plusieurs valeurs minimales, je suggère:
la source
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'utilisermin
pour trouver le minimum de cette liste.la source
Une autre approche pour résoudre le problème de plusieurs clés avec la même valeur min:
la source
Utiliser
min
avec un itérateur (pour python 3 utiliseritems
au lieu deiteritems
); au lieu de lambda, utilisez l'itemgetter
opérateur from, qui est plus rapide que lambda.la source
la source
J'ai comparé les performances des trois options suivantes:
Exemple de sortie:
la source
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:alors vous pouvez utiliser la fonction min comme suit:
cela a fonctionné pour moi.
la source
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
la source
la source
min()
).Est-ce ce que vous recherchez?
Imprime «quatorze»
la source