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?

4voto

Shameem Points 1025

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')

1voto

Giorgos Xou Points 177

Alors que la réponse de @SilentGhost fonctionne assez bien avec une seule longueur de clés, elle ne fonctionnera pas correctement pour ceux qui cherchent une solution avec des clés de "longueur multiple", et j'ai donc pensé à la solution ci-dessous [...]

Supposons que nous avons le dictionnaire ci-dessus et les clés que nous recherchons:

my_dict = {
    'key1':'KEY_1',
    ('tk1', 'tk2','tk3'):'TK_1_2_3',
    'key2':'KEY_2'
}

my_keys = ['key2','ke', 'tk2','k','key','exception'] # Les clés que je recherche

L'exemple et la SOLUTION ci-dessous:

for key in my_keys:
    print(next((v for k, v in my_dict.items() if (key == k) or (isinstance(k,tuple) and key in k)),None))

OUTPUT CORRECT :

KEY_2
None
TK_1_2_3
None
None
None

Alors qu'avec (une solution légèrement modifiée [pour éviter l'exception StopIteration] de) @SilentGhost answer

for key in my_keys:
    print(next((v for k, v in my_dict.items() if key in k),None)) # ajouté ((...),None)

les résultats sont INCORRECTS parce que [...]2 si ce n'est pas une exception StopIteration:

KEY_2
KEY_1
TK_1_2_3
KEY_1
KEY_1
None

Personnellement, je ne le recommanderais pas vraiment d'un point de vue d'efficacité de vitesse (du moins pas pour tous les cas d'utilisation), mais c'est effectivement une façon de résoudre ce problème et j'ai donc décidé de le publier.

0voto

classe MyDict(dict):
    def __setitem__(self, clés, valeur):
        if type(clés)!=tuple:clés=(clés,)
        pour clé in clés:super().__setitem__(clé,valeur)

monDict = MyDict()
monDict['a', 'c', 'd'] = 10
monDict['b', 'e'] = 20

print(monDict) # {'a': 10, 'c': 10, 'd': 10, 'b': 20, 'e': 20}

-1voto

tinker pony Points 1

Il y a une manière qui me vient à l'esprit. A toujours la limitation de n'avoir que les mêmes contenus.

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

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

for key in key_map:
    # boucler sur le dict

    if key_map[key] in key_map:
        # une clé est la valeur de l'autre

        target_key = key_map[key]
        key_map[key] = key_map[target_key]
        # écraser la clé avec le contenu de l'autre

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