101 votes

Est-il possible d'attribuer la même valeur à plusieurs clés dans un objet dict en une seule fois ?

En Python, j'ai besoin d'un objet dictionnaire qui ressemble à:

{'a': 10, 'b': 20, 'c': 10, 'd': 10, 'e': 20}

J'ai réussi à obtenir cela en combinant les fonctions dict.update() et dict.fromkeys() de la manière suivante:

myDict = {}
myDict.update(dict.fromkeys(['a', 'c', 'd'], 10))
myDict.update(dict.fromkeys(['b', 'e'], 20))

Cependant, comme le code est écrit pour des utilisateurs novices qui pourraient avoir besoin d'ajouter des clefs/valeurs de temps en temps, je préférerais une syntaxe simple minimaliste (de type Perl) comme:

myDict = {}
myDict['a', 'c', 'd'] = 10
myDict['b', 'e'] = 20

Cela me donne cependant:

myDict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}

Y a-t-il un moyen de simplifier mon premier exemple (en utilisant dict.update() et dict.fromkeys()) davantage, et d'obtenir l'objet dict que je recherche?

Ou, alternativement, si j'ai un dict avec des tuples comme dans mon deuxième exemple, y a-t-il un moyen facile pour moi de faire une recherche telle que myDict['c'] ou myDict.get('c') et d'obtenir la valeur 10?

122voto

SilentGhost Points 79627

Je dirais que ce que vous avez est très simple, vous pourriez légèrement l'améliorer en :

my_dict = dict.fromkeys(['a', 'c', 'd'], 10)
my_dict.update(dict.fromkeys(['b', 'e'], 20))

Si vos clés sont des tuples, vous pourriez faire :

>>> my_dict = {('a', 'c', 'd'): 10, ('b', 'e'): 20}
>>> next(v for k, v in my_dict.items() if 'c' in k)      # utiliser .iteritems() en python 2.x
10

Cela va bien sûr renvoyer la première valeur rencontrée pour laquelle la clé contient l'élément donné.

70voto

shao.lo Points 97

Similaire à @SilentGhost mais avec une syntaxe plus déclarative (avec Python 3.5+) que je préfère :

myDict = {
  **dict.fromkeys(['a', 'c', 'd'], 10), 
  **dict.fromkeys(['b', 'e'], 20)
}

14voto

taleinat Points 2525

Votre premier exemple peut être simplifié en utilisant une boucle:

myDict = {}
for key in ['a', 'c', 'd']:
    myDict[key] = 10
for key in ['b', 'e']:
    myDict[key] = 20

Aucune syntaxe spécialisée ou astuce, et je ne peux pas penser à quelque chose qui serait plus facile à comprendre.

Concernant votre deuxième question, il n'y a pas de moyen simple et efficace de faire la recherche comme dans votre deuxième exemple. Je ne peux penser qu'à itérer sur les clés (tuples) et vérifier si la clé est dans l'un d'eux, ce qui n'est pas ce que vous recherchez. Continuez à utiliser un dictionnaire simple avec les clés souhaitées.

En général, si vous visez un code qui peut être compris par des novices, restez aux bases telles que les conditions if et les boucles for/while.

13voto

wjandrea Points 1176

Union de dictionnaire (3.9+)

Maintenant avec Python 3.9, vous pouvez faire ceci :

myDict = dict.fromkeys(['a', 'c', 'd'], 10) | dict.fromkeys(['b', 'e'], 20)

Personnellement, je ne suis pas sûr que j'utiliserais cela, car c'est difficile à lire.

Compréhension de dictionnaire

myDict = {
    k: v
    for keys, v in [(['a', 'c', 'd'], 10), (['b', 'e'], 20)]
    for k in keys
    }

Ceci est également difficile à lire, mais je le mentionne pour des raisons de complétude.

référence

7voto

remosu Points 1549

Vous pourriez hériter de dict pour implémenter une sorte de "mise à jour à partir des clés":

class LazyDict(dict):
    def keylist(self, keys, value):
        for key in keys:
            self[key] = value

>>> d = LazyDict()
>>> d.keylist(('a', 'b', 'c'), 10)
>>> d
{'a': 10, 'c': 10, 'b': 10}

mais je préfère la solution de la boucle

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