web-dev-qa-db-fra.com

Comment utiliser if / else dans une compréhension du dictionnaire?

En python2.7 +, il n’existe aucun moyen de créer quelque chose comme:

{ something_if_true if condition else something_if_false for key, value in dict_.items() }

Je sais que tu peux faire n'importe quoi avec juste 'si'

{ something_if_true for key, value in dict_.items() if condition}
96
diegueus9

Vous l'avez déjà: A if test else B est une expression python valide. Le seul problème avec votre compréhension de la dictée est que l'emplacement d'une expression dans une compréhension de dict doit comporter deux expressions séparées par un signe deux-points:

{ (some_key if condition else default_key):(something_if_true if condition 
          else something_if_false) for key, value in dict_.items() }

La clause finale if agit en tant que filtre, ce qui est différent du fait de disposer de l'expression conditionnelle.

175
Marcin

@ la réponse de Marcin couvre tout, mais juste au cas où quelqu'un voudrait voir un exemple réel, j'en ajoute deux ci-dessous:

Disons que vous avez le dictionnaire d'ensembles suivant

d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}

et vous voulez créer un nouveau dictionnaire dont les clés indiquent si la chaîne 'a' est contenu ou non dans les valeurs, vous pouvez utiliser

dout = {"a_in_values_of_{}".format(k) if 'a' in v else "a_not_in_values_of_{}".format(k): v for k, v in d.items()}

qui donne

{'a_in_values_of_key1': {'a', 'b', 'c'},
 'a_not_in_values_of_key2': {'bar', 'foo'},
 'a_not_in_values_of_key3': {'sad', 'so'}}

Supposons maintenant que vous avez deux dictionnaires comme celui-ci

d1 = {'bad_key1': {'a', 'b', 'c'}, 'bad_key2': {'foo', 'bar'}, 'bad_key3': {'so', 'sad'}}
d2 = {'good_key1': {'foo', 'bar', 'xyz'}, 'good_key2': {'a', 'b', 'c'}}

et vous voulez remplacer les clés dans d1 par les touches de d2 si leurs valeurs respectives sont identiques, vous pouvez le faire

# here we assume that the values in d2 are unique
# Python 2
dout2 = {d2.keys()[d2.values().index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}

# Python 3
dout2 = {list(d2.keys())[list(d2.values()).index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}

qui donne

{'bad_key2': {'bar', 'foo'},
 'bad_key3': {'sad', 'so'},
 'good_key2': {'a', 'b', 'c'}}
7
Cleb