Suppression de plusieurs clés d'un dictionnaire en toute sécurité

Je sais supprimer une entrée, 'key' de mon dictionnaire d, en toute sécurité, vous le 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 devrai 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 une façon plus intelligente de le faire?

78
demandé sur MERose 2012-01-25 03:05:51

9 réponses

Pourquoi pas comme ceci:

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]

Une version plus compacte a été fournie par mattbornski en utilisant dict.pop()

35
répondu Glaslos 2018-01-16 08:22:04
d = {'some':'data'}
entriesToRemove = ('any', 'iterable')
for k in entriesToRemove:
    d.pop(k, None)
158
répondu mattbornski 2012-01-24 23:22:05

En Utilisant Dict Compréhensions

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

key1 et cle2 doivent être supprimées.

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}
>>> 
61
répondu Abhijeet Rastogi 2012-01-28 19:29:19

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 juste pour la suppression des clés de d, mais vous créeriez inutilement la liste de valeurs avec la compréhension de la liste. Il est également un peu difficile d'utiliser une compréhension de liste juste pour l'effet secondaire de la fonction.

16
répondu Andrew Clark 2012-01-24 23:27:52

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 obtenez:

{'c': 3}
13
répondu Jose Ricardo Bustos M. 2016-11-28 20:26:11

Je n'ai aucun problème avec l'une 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
répondu Doug R. 2017-05-23 10:31:14

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 existe sûrement d'autres moyens, peut-être avec des compréhensions de dictionnaire:

entriestoremove = (2,5,1)
newdict = {x for x in d if x not in entriestoremove}
2
répondu L3viathan 2013-09-30 14:05:42

Inline

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
répondu chuang wang 2016-10-27 05:14:26

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 tel.

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

Ensuite, utilisez pop() dans une compréhension de liste, ou for loop, pour itérer sur les clés et pop une à la fois en tant que telle.

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

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

0
répondu Terrance DeJesus 2018-05-16 22:55:46