114 votes

Python: si la clé dans le dict vs try/except

J'ai une question sur les expressions idiomatiques et la lisibilité, et il semble y avoir un conflit de Python philosophies pour ce cas particulier:

Je veux construire Un dictionnaire de dictionnaire B. Si la clé n'existe pas dans B, alors ne rien faire et continuer sur.

Ce qui est mieux?

try:
    A["blah"] = B["blah"]
except KeyError:
    pass

ou

if "blah" in B:
    A["blah"] = B["blah"]

"Faire et de demander pardon" vs "la simplicité et de la clarté".

Ce qui est mieux et pourquoi?

85voto

Glenn Maynard Points 24451

Les Exceptions ne sont pas conditionnelles.

Le conditionnel version est plus claire. C'est naturel: c'est simple, le contrôle de flux, qui est ce que les conditions sont conçus pour, non des exceptions.

L'exception de la version est principalement utilisé comme une optimisation de faire ces recherches dans une boucle: pour certains algorithmes, il permet d'éliminer les tests de boucles internes. Il n'a pas que des avantages ici. Il a le petit avantage qu'elle permet d'éviter d'avoir à dire "blah" deux fois, mais si vous faites beaucoup de ceux-ci, vous devriez probablement demander à un assistant move_key de la fonction, de toute façon.

En général, je recommanderais fortement de coller avec le conditionnel version par défaut, sauf si vous avez une raison particulière de ne pas. Les conditions sont les évidentes façon de le faire, ce qui est généralement une forte recommandation de privilégier une solution plutôt que l'autre.

85voto

lqc Points 2498

Il y a aussi une troisième voie qui évite à la fois les exceptions et double-recherche, qui peut être important si la recherche est cher:

value = B.get("blah", None)
if value is not None: 
    A["blah"] = value

Dans le cas où vous vous attendez le dictionnaire pour contenir None valeurs, vous pouvez utiliser un peu plus ésotérique des constantes comme NotImplemented, Ellipsis ou créer un nouveau:

MyConst = object()
def update_key(A, B, key):
    value = B.get(key, MyConst)
    if value is not MyConst: 
        A[key] = value

De toute façon, à l'aide de update() est le plus lisible option pour moi:

a.update((k, b[k]) for k in ("foo", "bar", "blah") if k in b)

14voto

pyfunc Points 31088

Ce que je comprends, vous voulez mettre à jour dict Un avec la clé,la valeur des paires de dict B

update est un meilleur choix.

A.update(B)

Exemple:

>>> A = {'a':1, 'b': 2, 'c':3}
>>> B = {'d': 2, 'b':5, 'c': 4}
>>> A.update(B)
>>> A
{'a': 1, 'c': 4, 'b': 5, 'd': 2}
>>> 

10voto

Sami Lehtinen Points 354

Citation directe à partir de Python performance wiki:

Sauf pour la première fois, à chaque fois qu'un mot est vu l'instruction si le test échoue. Si vous êtes à la prise en compte d'un grand nombre de mots, beaucoup vont probablement se produire plusieurs fois. Dans une situation où l'initialisation d'une valeur ne va se produire une fois et l'augmentation de la valeur qui va se produire à plusieurs reprises, il est moins coûteux d'utiliser une instruction try.

Il semble donc que les deux options sont viables en fonction de la situation. Pour plus de détails, vous pouvez vérifier ce lien: Essayez-à l'exception de performance

3voto

neil Points 1153

Je pense que la règle générale ici est - A["blah"] existent normalement, si oui, essayez-à l'exception de est bonne si elle n'est pas alors utiliser if "blah" in b:

Je pense à "essayer" est pas cher dans le temps, mais "à l'exception" c'est plus cher.

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