web-dev-qa-db-fra.com

Supprimer plusieurs clés d'un dictionnaire en toute sécurité

Je sais que pour supprimer une entrée, 'clé' de mon dictionnaire d, en toute sécurité, vous faites:

if d.has_key('key'):
    del d['key']

Cependant, je dois supprimer plusieurs entrées du dictionnaire en toute sécurité. Je pensais définir les entrées dans un tuple car je devrais le faire plus d'une fois.

entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
    if d.has_key(x):
        del d[x]

Cependant, je me demandais s'il y avait un moyen plus intelligent de le faire?

88
dublintech

Pourquoi pas comme ça:

entries = ('a', 'b', 'c')
the_dict = {'b': 'foo'}

def entries_to_remove(entries, the_dict):
    for key in entries:
        if key in the_dict:
            del the_dict[key]

Mattbornski a fourni une version plus compacte avec dict.pop ()

37
Glaslos
d = {'some':'data'}
entriesToRemove = ('any', 'iterable')
for k in entriesToRemove:
    d.pop(k, None)
177
mattbornski

Utilisation de Dict Comprehensions

final_dict = {key: t[key] for key in t if key not in [key1, key2]}

key1 et key2 doivent être supprimés.

Dans l'exemple ci-dessous, les clés "b" et "c" doivent être supprimées et conservées dans une liste de clés.

>>> a
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
>>> keys = ["b", "c"]
>>> print {key: a[key] for key in a if key not in keys}
{'a': 1, 'd': 4}
>>> 
72
Abhijeet Rastogi

Si vous deviez également récupérer les valeurs des clés que vous supprimez, ce serait un très bon moyen de le faire:

valuesRemoved = [d.pop(k, None) for k in entitiesToRemove]

Vous pouvez bien sûr toujours le faire uniquement pour supprimer les clés de d, mais vous créeriez inutilement la liste de valeurs avec la compréhension Il est également un peu incertain d’utiliser une compréhension de liste uniquement pour l’effet secondaire de la fonction.

17
Andrew Clark

une solution utilise les fonctions map et filter

python 2

d={"a":1,"b":2,"c":3}
l=("a","b","d")
map(d.__delitem__, filter(d.__contains__,l))
print(d)

python 3

d={"a":1,"b":2,"c":3}
l=("a","b","d")
list(map(d.__delitem__, filter(d.__contains__,l)))
print(d)

vous recevez:

{'c': 3}
13

Je n'ai aucun problème avec aucune des réponses existantes, mais j'ai été surpris de ne pas trouver cette solution:

keys_to_remove = ['a', 'b', 'c']
my_dict = {k: v for k, v in Zip("a b c d e f g".split(' '), [0, 1, 2, 3, 4, 5, 6])}

for k in keys_to_remove:
    try:
        del my_dict[k]
    except KeyError:
        pass

assert my_dict == {'d': 3, 'e': 4, 'f': 5, 'g': 6}

Note: je suis tombé sur cette question venant de ici . Et ma réponse est liée à cette réponse .

4
Doug R.

Pourquoi pas:

entriestoremove = (2,5,1)
for e in entriestoremove:
    if d.has_key(e):
        del d[e]

Je ne sais pas ce que vous entendez par "manière plus intelligente". Il y a sûrement d'autres moyens, peut-être avec la compréhension du dictionnaire:

entriestoremove = (2,5,1)
newdict = {x for x in d if x not in entriestoremove}
2
L3viathan

en ligne

import functools

#: not key(c) in d
d = {"a": "avalue", "b": "bvalue", "d": "dvalue"}

entitiesToREmove = ('a', 'b', 'c')

#: python2
map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove)

#: python3

list(map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove))

print(d)
# output: {'d': 'dvalue'}
1
chuang wang

A trouvé une solution avec pop et map

d = {'a': 'valueA', 'b': 'valueB', 'c': 'valueC', 'd': 'valueD'}
keys = ['a', 'b', 'c']
list(map(d.pop, keys))
print(d)

La sortie de ceci:

{'d': 'valueD'}

J'ai répondu à cette question si tard, simplement parce que je pense que cela aiderait pour l'avenir si quelqu'un cherchait la même chose. Et cela pourrait aider.

1
Shubham Srivastava

Voici une autre solution simple ligne sans conversion de carte en liste:

d = {'a': 1, 'b': 2, 'c': 3}
entities_to_remove = {'a', 'c'}

all(d.pop(x, None) for x in entities_to_remove)
0
Denis Busalaev

Je pense qu'en utilisant le fait que les clés puissent être traitées comme un ensemble, c'est le moyen le plus agréable si vous utilisez Python 3

def remove_keys(d, keys):
    to_remove = set(keys)
    filtered_keys = d.keys() - to_remove
    filtered_values = map(d.get, filtered_keys)
    return dict(Zip(filtered_keys, filtered_values))

Exemple:

>>> remove_keys({'k1': 1, 'k3': 3}, ['k1', 'k2'])
{'k3': 3}
0
Reut Sharabani

Je suis en retard à cette discussion mais pour quelqu'un d'autre. Une solution peut être de créer une liste de clés en tant que telle.

k = ['a','b','c','d']

Ensuite, utilisez pop () dans une liste de compréhension, ou une boucle, pour parcourir les touches et faire apparaître une à la fois.

new_dictionary = [dictionary.pop(x, 'n/a') for x in k]

Le 'n/a' est dans le cas où la clé n'existe pas, une valeur par défaut doit être renvoyée.

0
Terrance DeJesus