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

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

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

J'ai pu l'obtenir avec succès en combinant les fonctions dict.update() et dict.fromkeys() comme ceci:

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

Cependant, parce que le code est écrit pour les utilisateurs novices qui peuvent avoir besoin de faire ajouter des clés/valeurs à l'occasion, je préférerais une syntaxe simple (Perl-like) telle que:

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

Ceci, cependant, me donne:

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

Existe-t-il un moyen de simplifier mon premier exemple (en utilisant dict.update() et dict.fromkeys()) plus loin, et obtenir l'objet dict que je cherche?

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 obtenir la valeur 10?

32
demandé sur SilentGhost 2010-06-04 16:23:08

6 réponses

Je dirais que ce que vous avez est Très simple, vous pourriez l'améliorer légèrement pour être:

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

Si vos clés sont tuple vous pouvez faire:

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

Ceci est, bien sûr, retournera la première valeur rencontrée, clé pour laquelle contient un élément donné.

39
répondu SilentGhost 2010-06-04 12:31:10

Similaire à @SilentGhost mais une syntaxe plus déclarative que je préfère:

myDict = {
  **dict.fromkeys(['a', 'b', 'c'], 10), 
  **dict.fromkeys(['b', 'e'], 20)
}
7
répondu shao.lo 2017-08-28 23:22:07

Pourquoi ne pas hériter de dict?

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 boucle

6
répondu remosu 2010-06-04 13:28:18

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

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

En ce qui concerne 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 peux seulement penser à itérer sur les clés (tuples) et vérifier si la clé est dans l'une d'entre elles, ce qui n'est pas ce que vous cherchez. S'en tenir à l'aide d'un dict simple avec les touches que vous vouloir.

En général, si vous visez du code qui peut être compris par les novices, respectez les bases telles que if conditions et for / while loops.

5
répondu taleinat 2010-06-04 12:39:07

Méthode:

def multi_key_dict_get(d, k):
    for keys, v in d.items():
        if k in keys:
            return v
    return None

Utilisation:

my_dict = {
   ('a', 'b', 'c'): 10,
   ('p', 'q', 'r'): 50
}

value = multi_key_dict_get(my_dict, 'a')
0
répondu Shameem 2018-04-26 04:51:02

Il y a une façon qui vient à l'esprit. A toujours la limitation de n'avoir que le même contenu.

La valeur d'une clé ne peut pas en changer une autre.

key_map = {   
    'KEY_UP':move_up,
    'w':'KEY_UP',
}

Pour la clé dans key_map:

# loop over the `dict`

if key_map[key] in key_map:
    # one key is the value of the other

    target_key = key_map[key]
    key_map[key] = key_map[target_key]
    # overwrite key white the ontents of the other
0
répondu tinker pony 2018-07-28 17:30:54