299 votes

python : Comment vérifier que plusieurs clés se trouvent dans un dict en une seule fois ?

Je veux faire quelque chose comme :

foo = {'foo':1,'zip':2,'zam':3,'bar':4}

if ("foo","bar") in foo:
    #do stuff

Je ne sais pas si c'est possible mais j'aimerais le savoir :-)

23voto

Greg Points 2980

Et si

if all([key in foo for key in ["foo","bar"]]):
    #do stuff
    pass

4voto

John Machin Points 39706

La solution d'Alex Martelli set(queries) <= set(my_dict) est le code le plus court mais peut ne pas être le plus rapide. Supposons que Q = len(queries) et D = len(my_dict).

Il faut O(Q) + O(D) pour créer les deux ensembles, puis (on l'espère !) seulement O(min(Q,D)) pour effectuer le test du sous-ensemble -- en supposant bien sûr que la recherche de l'ensemble Python est O(1) -- c'est le pire cas (quand la réponse est Vrai).

La solution de générateur de hughdbrown (et al ?) all(k in my_dict for k in queries) est dans le pire des cas O(Q).

Facteurs de complication :
(1) les boucles dans le gadget basé sur les ensembles sont toutes effectuées à la vitesse du C, alors que le gadget basé sur n'importe quel ensemble boucle sur du bytecode.
(2) L'appelant du gadget any-based peut être capable d'utiliser toute connaissance de la probabilité d'échec pour ordonner les éléments de la requête en conséquence, alors que le gadget set-based ne permet pas un tel contrôle.

Comme toujours, si la vitesse est importante, il est bon de procéder à une analyse comparative dans des conditions opérationnelles.

1voto

rein Points 140

Et si on utilisait des lambdas ?

 if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff

1voto

Jochen Ritzel Points 42916

Au cas où vous le voudriez :

  • obtenir également les valeurs des clés
  • vérifier plus d'un dictonaire

alors :

from operator import itemgetter
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
keys = ("foo","bar") 
getter = itemgetter(*keys) # returns all values
try:
    values = getter(foo)
except KeyError:
    # not both keys exist
    pass

1voto

Jason Baker Points 56682

Je ne veux pas dire que vous n'y avez pas pensé, mais je trouve que les choses les plus simples sont généralement les meilleures :

if ("foo" in foo) and ("bar" in foo):
    # do stuff

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X