问题:从字典中删除元素
有没有办法从Python的字典中删除项目?
另外,如何从字典中删除项目以返回副本(即不修改原始内容)?
回答 0
该del
语句删除一个元素:
del d[key]
但是,这会使现有字典发生变化,因此对于引用同一实例的其他任何人,字典的内容都会更改。要返回新词典,请复制该词典:
def removekey(d, key):
r = dict(d)
del r[key]
return r
该dict()
构造使得浅拷贝。要进行深拷贝,请参阅copy
模块。
请注意,为每个字典del
/ assignment / etc 复制一份。意味着您要从恒定时间变为线性时间,并且还要使用线性空间。对于小命令,这不是问题。但是,如果您打算复制大量大型字典,则可能需要不同的数据结构,例如HAMT(如本答案所述)。
回答 1
回答 2
我认为您的解决方案是最好的方法。但是,如果您需要其他解决方案,则可以使用旧字典中的键来创建新字典,而无需包括指定的键,如下所示:
>>> a
{0: 'zero', 1: 'one', 2: 'two', 3: 'three'}
>>> {i:a[i] for i in a if i!=0}
{1: 'one', 2: 'two', 3: 'three'}
回答 3
该del语句是你在找什么。如果您有一个名为foo的字典,其键名为“ bar”,则可以从foo中删除“ bar”,如下所示:
del foo['bar']
请注意,这将永久修改正在操作的词典。如果要保留原始词典,则必须事先创建一个副本:
>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}
该dict
调用将进行浅表复制。如果要深拷贝,请使用copy.deepcopy
。
为了方便起见,您可以使用以下方法复制和粘贴:
def minus_key(key, dictionary):
shallow_copy = dict(dictionary)
del shallow_copy[key]
return shallow_copy
回答 4
有很多不错的答案,但我想强调一件事。
您可以同时使用dict.pop()
方法和更通用的del
语句从字典中删除项目。它们都变异了原始词典,因此您需要进行复制(请参见下面的详细信息)。
KeyError
如果您要提供给他们的密钥在词典中不存在,则这两个都将引发一个:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
和
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
您必须注意以下事项:
通过捕获异常:
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
del d[key_to_remove]
except KeyError as ex:
print("No such key: '%s'" % ex.message)
和
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
d.pop(key_to_remove)
except KeyError as ex:
print("No such key: '%s'" % ex.message)
通过执行检查:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
和
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
但是pop()
还有一种更简洁的方法-提供默认的返回值:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
除非您pop()
用来获取要删除的键的值,否则可以提供任何必要的信息None
。虽然可能由于with函数本身具有复杂性而导致开销,所以del
with in
check的使用略快一些pop()
。通常情况并非如此,因此pop()
使用默认值就足够了。
对于主要问题,您必须复制字典,以保存原始字典,并在不删除密钥的情况下新建一个字典。
这里的其他一些人建议使用进行完整(较深)的副本copy.deepcopy()
,这可能是一个过大的杀伤力,而使用copy.copy()
或则dict.copy()
可能是“正常”(较浅)的副本,可能就足够了。字典保留对对象的引用作为键的值。因此,当您从字典中删除键时,该引用将被删除,而不是被引用的对象。如果内存中没有其他引用,则垃圾回收器随后可以自动删除该对象本身。与浅拷贝相比,进行深拷贝需要更多的计算,因此,通过进行深拷贝,浪费内存并为GC提供更多工作,它会降低代码性能,有时浅拷贝就足够了。
但是,如果您将可变对象作为字典值,并计划以后在不带键的情况下在返回的字典中对其进行修改,则必须进行深拷贝。
使用浅拷贝:
def get_dict_wo_key(dictionary, key):
"""Returns a **shallow** copy of the dictionary without a key."""
_dict = dictionary.copy()
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
使用深拷贝:
from copy import deepcopy
def get_dict_wo_key(dictionary, key):
"""Returns a **deep** copy of the dictionary without a key."""
_dict = deepcopy(dictionary)
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
回答 5
…如何从字典中删除项目以返回副本(即不修改原始内容)?
A dict
是用于此的错误数据结构。
当然,复制dict并从复制中弹出是可行的,利用理解力构建新dict也是如此,但是所有复制都需要时间-您已经用线性时间操作替换了恒定时间操作。并且所有这些活着的副本立刻占据了空间-每个副本的线性空间。
其他数据结构(例如哈希数组映射尝试)也正是针对这种用例而设计的:添加或删除元素会以对数时间返回一个副本,并将其大部分存储与原始共享。1个
当然也有一些缺点。性能是对数而不是常数(尽管基数较大,通常为32-128)。而且,尽管您可以使非变异API与相同dict
,但“变异” API显然是不同的。而且,最重要的是,Python不附带HAMT电池。2
该pyrsistent
库是基于HAMT的dict-replacement(以及各种其他类型)的Python相当可靠的实现。它甚至还有一个漂亮的Evolutioner API,用于尽可能平滑地将现有的变异代码移植到持久代码中。但是,如果您想明确地表示要返回副本而不是进行变异,则可以像这样使用它:
>>> from pyrsistent import m
>>> d1 = m(a=1, b=2)
>>> d2 = d1.set('c', 3)
>>> d3 = d1.remove('a')
>>> d1
pmap({'a': 1, 'b': 2})
>>> d2
pmap({'c': 3, 'a': 1, 'b': 2})
>>> d3
pmap({'b': 2})
这d3 = d1.remove('a')
正是这个问题所要的。
如果您有可变的数据结构(例如)dict
并list
嵌入到中pmap
,则仍然会出现别名问题-您只能通过将pmap
s和pvector
s 嵌入所有位置来实现不可变,以解决此问题。
1. HAMT在Scala,Clojure和Haskell等语言中也很流行,因为它们在无锁编程和软件事务存储中的表现非常好,但是在Python中它们都不重要。
2.事实上,是在一个STDLIB HAMT,在执行中使用contextvars
。较早撤消的PEP解释了原因。但这是库的隐藏实现细节,而不是公共集合类型。
回答 6
d = {1: 2, '2': 3, 5: 7}
del d[5]
print 'd = ', d
结果: d = {1: 2, '2': 3}
回答 7
只需调用del d [‘key’]。
但是,在生产中,始终最好检查d中是否存在“密钥”。
if 'key' in d:
del d['key']
回答 8
不,除了
def dictMinus(dct, val):
copy = dct.copy()
del copy[val]
return copy
但是,通常仅创建略有变化的字典的副本可能不是一个好主意,因为这将导致相对较大的内存需求。通常最好记录旧字典(如果需要的话),然后对其进行修改。
回答 9
# mutate/remove with a default
ret_val = body.pop('key', 5)
# no mutation with a default
ret_val = body.get('key', 5)
回答 10
>>> def delete_key(dict, key):
... del dict[key]
... return dict
...
>>> test_dict = {'one': 1, 'two' : 2}
>>> print delete_key(test_dict, 'two')
{'one': 1}
>>>
这不会进行任何错误处理,它假定键在字典中,您可能需要先检查一下,raise
如果没有
回答 11
这里是一种顶层设计方法:
def eraseElement(d,k):
if isinstance(d, dict):
if k in d:
d.pop(k)
print(d)
else:
print("Cannot find matching key")
else:
print("Not able to delete")
exp = {'A':34, 'B':55, 'C':87}
eraseElement(exp, 'C')
我正在将字典和想要的键传递到函数中,验证它是否是字典,并且键是否还可以,如果两者都存在,则从字典中删除值并打印出剩余的值。
输出: {'B': 55, 'A': 34}
希望有帮助!
回答 12
下面的代码段绝对会帮助您,我在每一行中添加了注释,这将有助于您理解代码。
def execute():
dic = {'a':1,'b':2}
dic2 = remove_key_from_dict(dic, 'b')
print(dict2) # {'a': 1}
print(dict) # {'a':1,'b':2}
def remove_key_from_dict(dictionary_to_use, key_to_delete):
copy_of_dict = dict(dictionary_to_use) # creating clone/copy of the dictionary
if key_to_delete in copy_of_dict : # checking given key is present in the dictionary
del copy_of_dict [key_to_delete] # deleting the key from the dictionary
return copy_of_dict # returning the final dictionary
或者你也可以使用dict.pop()
d = {"a": 1, "b": 2}
res = d.pop("c") # No `KeyError` here
print (res) # this line will not execute
或更好的方法是
res = d.pop("c", "key not found")
print (res) # key not found
print (d) # {"a": 1, "b": 2}
res = d.pop("b", "key not found")
print (res) # 2
print (d) # {"a": 1}
回答 13
这是使用列表理解的另一个变体:
original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.iteritems() if v)
# result should be {'b': 'Some'}
该方法基于本文的答案:一种 有效的方法来从字典中删除带有空字符串的键
回答 14
species = {'HI': {'1': (1215.671, 0.41600000000000004),
'10': (919.351, 0.0012),
'1025': (1025.722, 0.0791),
'11': (918.129, 0.0009199999999999999),
'12': (917.181, 0.000723),
'1215': (1215.671, 0.41600000000000004),
'13': (916.429, 0.0005769999999999999),
'14': (915.824, 0.000468),
'15': (915.329, 0.00038500000000000003),
'CII': {'1036': (1036.3367, 0.11900000000000001), '1334': (1334.532, 0.129)}}
以下代码将复制字典species
并删除不在目录中的项目trans_HI
trans_HI=['1025','1215']
for transition in species['HI'].copy().keys():
if transition not in trans_HI:
species['HI'].pop(transition)