我知道要从我的字典d
中删除一个条目'key',安全地执行:
if d.has_key('key'):
del d['key']
但是,我需要安全地从字典中删除多个条目。我正在考虑在元组中定义条目,因为我需要多次执行此操作。
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
但是,我想知道是否有更聪明的方法来做到这一点?
答案 0 :(得分:182)
d = {'some':'data'}
entriesToRemove = ('any', 'iterable')
for k in entriesToRemove:
d.pop(k, None)
答案 1 :(得分:72)
使用 Dict理解
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}
>>>
答案 2 :(得分:37)
为什么不喜欢这样:
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使用dict.pop()
提供了更紧凑的版本答案 3 :(得分:17)
如果您还需要检索要删除的键的值,这将是一个非常好的方法:
valuesRemoved = [d.pop(k, None) for k in entitiesToRemove]
您当然可以仅仅为了从d
删除密钥而执行此操作,但是您将不必要地使用列表推导创建值列表。对于函数的副作用,使用列表推导也有点不清楚。
答案 4 :(得分:15)
解决方案是使用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}
答案 5 :(得分:4)
我对任何现有答案都没有任何问题,但我很惊讶没有找到这个解决方案:
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}
注意:我偶然发现了来自here的这个问题。我的回答与this answer有关。
答案 6 :(得分:4)
对cpython 3的一些计时测试表明,简单的for循环是最快的方法,并且可读性强。添加函数也不会造成太多开销:
timeit结果(10000次迭代):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
def del_all(mapping, to_remove):
"""Remove list of elements from mapping."""
for key in to_remove:
del mapping[key]
对于小迭代,由于函数调用的开销,执行“内联”要快一些。但是del_all
是不掉毛安全的,可重用的,并且比所有python理解和映射构造都快。
答案 7 :(得分:3)
找到了pop
和map
的解决方案
d = {'a': 'valueA', 'b': 'valueB', 'c': 'valueC', 'd': 'valueD'}
keys = ['a', 'b', 'c']
list(map(d.pop, keys))
print(d)
此输出:
{'d': 'valueD'}
我这么晚回答了这个问题,只是因为我认为如果有人进行搜索,将来会有所帮助。这可能会有帮助。
更新
如果字典中不存在键,则以上代码将引发错误。
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'}
答案 8 :(得分:2)
为什么不:
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}
答案 9 :(得分:2)
<强>内联强>
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'}
答案 10 :(得分:1)
我已经测试了三种方法的性能:
# Method 1: `del`
for key in remove_keys:
if key in d:
del d[key]
# Method 2: `pop()`
for key in remove_keys:
d.pop(key, None)
# Method 3: comprehension
{key: v for key, v in d.items() if key no in remove_keys}
这是一百万次迭代的结果:
del
:2.03s 2.0 ns / iter(100%)pop()
:2.38秒2.4 ns / iter(117%)因此del
和pop()
都是最快的。理解速度要慢2倍。
但是无论如何,我们在这里说 nanoseconds :)Python中的字典非常快。
答案 11 :(得分:0)
如果您使用的是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}
答案 12 :(得分:0)
最好完全支持字典的set方法(而不是我们在Python 3.9中遇到的麻烦),以便您可以简单地“删除”一组键。但是,只要不是这种情况,并且您有一个大型词典并且可能要删除大量键,则可能需要了解性能。因此,我创建了一些代码,该代码创建的大小足以进行有意义的比较:100,000 x 1000矩阵,因此总共10,000,00个项目。
from itertools import product
from time import perf_counter
# make a complete worksheet 100000 * 1000
start = perf_counter()
prod = product(range(1, 100000), range(1, 1000))
cells = {(x,y):x for x,y in prod}
print(len(cells))
print(f"Create time {perf_counter()-start:.2f}s")
clock = perf_counter()
# remove everything above row 50,000
keys = product(range(50000, 100000), range(1, 100))
# for x,y in keys:
# del cells[x, y]
for n in map(cells.pop, keys):
pass
print(len(cells))
stop = perf_counter()
print(f"Removal time {stop-clock:.2f}s")
1000万或更多的项目在某些情况下并不罕见。比较本地计算机上的这两种方法,我发现在使用map
和pop
时有一些改进,大概是因为调用的函数较少,但是在我的计算机上都花费了大约2.5s。但是,与首先创建字典(55s)或在循环中包括检查所需的时间相比,这显得苍白。如果可能,那么最好创建一个集合,该集合是字典键和过滤器的交集:
keys = cells.keys() & keys
总而言之:del
已经过优化,所以不用担心使用它。
答案 13 :(得分:0)
另一种从字典中删除键列表的 map() 方法
并避免引发 KeyError 异常
dic = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
keys_to_remove = ['key_not_exist', 'key1', 'key2', 'key3']
k = list(map(dic.pop, keys_to_remove, keys_to_remove))
print('k=', k)
print('dic after = \n', dic)
**this will produce output**
k= ['key_not_exist', 1, 2, 3]
dic after = {'key4': 4, 'key5': 5}
Duplicate keys_to_remove
是人为的,它需要为 dict.pop() 函数提供默认值。
你可以在这里添加任何数组 len_ = len(key_to_remove)
例如
dic = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
keys_to_remove = ['key_not_exist', 'key1', 'key2', 'key3']
k = list(map(dic.pop, keys_to_remove, np.zeros(len(keys_to_remove))))
print('k=', k)
print('dic after = ', dic)
** 将产生输出 **
k= [0.0, 1, 2, 3]
dic after = {'key4': 4, 'key5': 5}
答案 14 :(得分:0)
def delete_keys_from_dict(dictionary, keys):
"""
Deletes the unwanted keys in the dictionary
:param dictionary: dict
:param keys: list of keys
:return: dict (modified)
"""
from collections.abc import MutableMapping
keys_set = set(keys)
modified_dict = {}
for key, value in dictionary.items():
if key not in keys_set:
if isinstance(value, list):
modified_dict[key] = list()
for x in value:
if isinstance(x, MutableMapping):
modified_dict[key].append(delete_keys_from_dict(x, keys_set))
else:
modified_dict[key].append(x)
elif isinstance(value, MutableMapping):
modified_dict[key] = delete_keys_from_dict(value, keys_set)
else:
modified_dict[key] = value
return modified_dict
_d = {'a': 1245, 'b': 1234325, 'c': {'a': 1245, 'b': 1234325}, 'd': 98765,
'e': [{'a': 1245, 'b': 1234325},
{'a': 1245, 'b': 1234325},
{'t': 767}]}
_output = delete_keys_from_dict(_d, ['a', 'b'])
_expected = {'c': {}, 'd': 98765, 'e': [{}, {}, {'t': 767}]}
print(_expected)
print(_output)
答案 15 :(得分:-1)
我迟到了这个讨论,但对其他人来说。解决方案可能是创建一个密钥列表。
k = ['a','b','c','d']
然后在列表推导或for循环中使用pop()迭代键并一次弹出一个键。
new_dictionary = [dictionary.pop(x, 'n/a') for x in k]
如果密钥不存在,则“n / a”需要返回默认值。