Безопасное удаление нескольких ключей из словаря - PullRequest
93 голосов
/ 25 января 2012

Я знаю, чтобы удалить запись, «ключ» из моего словаря. d, безопасно, вы делаете:

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

Однако мне нужно безопасно удалить несколько записей из словаря.Я думал об определении записей в кортеже, поскольку мне нужно будет делать это более одного раза.

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

Однако мне было интересно, есть ли более разумный способ сделать это?

Ответы [ 11 ]

189 голосов
/ 25 января 2012
d = {'some':'data'}
entriesToRemove = ('any', 'iterable')
for k in entriesToRemove:
    d.pop(k, None)
73 голосов
/ 25 января 2012

Использование Dict Conpretions

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

, где key1 и key2 должны быть удалены.

В приведенном ниже примере ключи "b" и "c" должны быть удалены, и они хранятся в списке ключей.

>>> 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}
>>> 
39 голосов
/ 25 января 2012

Почему бы не так:

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]

Более компактная версия была предоставлена ​​Маттборнски с использованием dict.pop ()

18 голосов
/ 20 мая 2015

решение использует функции map и 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)

Вы получите:

{'c': 3}
17 голосов
/ 25 января 2012

Если вам также необходимо получить значения для ключей, которые вы удаляете, это был бы довольно хороший способ сделать это:

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

Конечно, вы все равно могли бы сделать это только для удаления ключей из d, но вы бы без необходимости создавали список значений с пониманием списка. Также немного неясно использовать списочный анализ только для побочного эффекта функции.

4 голосов
/ 20 мая 2015

У меня нет проблем ни с одним из существующих ответов, но я был удивлен, что не нашел этого решения:

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}

Примечание: я наткнулся на этот вопрос из здесь . И мой ответ связан с этим ответом .

3 голосов
/ 24 января 2019

Нашел решение с pop и map

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

Вывод этого:

{'d': 'valueD'}

Я так поздно ответил на этот вопрос только потому, что думаю, что так и будетПомощь в будущем, если кто-то ищет то же самое.И это может помочь.

Обновление

Приведенный выше код выдаст ошибку, если ключ не существует в dict.

DICTIONARY = {'a': 'valueA', 'b': 'valueB', 'c': 'valueC', 'd': 'valueD'}
keys = ['a', 'l', 'c']

def remove_keys(key):
    try:
        DICTIONARY.pop(key, None)
    except:
        pass  # or do any action

list(map(remove_key, keys))
print(DICTIONARY)

вывод:

DICTIONARY = {'b': 'valueB', 'd': 'valueD'}
2 голосов
/ 27 октября 2016

встроенный

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'}
2 голосов
/ 25 января 2012

Почему бы и нет:

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

Я не знаю, что вы подразумеваете под "умнее". Конечно, есть и другие способы, возможно, со словарным пониманием:

entriestoremove = (2,5,1)
newdict = {x for x in d if x not in entriestoremove}
0 голосов
/ 11 марта 2019

Я думаю, использование того факта, что ключи можно рассматривать как набор, является наилучшим способом, если вы работаете на 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))

Пример:

>>> remove_keys({'k1': 1, 'k3': 3}, ['k1', 'k2'])
{'k3': 3}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...