从字典中删除一个项目
有没有办法从Python中的字典中删除项目?
我知道我可以在字典上调用.pop
,但返回的是删除的项目。 我正在寻找的东西返回字典减去元素的问题。
目前我有一个帮助函数,接受有问题的字典作为参数,然后返回一个字典删除项目,是否有一个更优雅的解决scheme?
del
语句删除一个元素:
del d[key]
但是,这会改变现有的字典,使得字典的内容为其他引用同一个实例的其他人改变。 要返回一个新的字典,请复制字典:
def removekey(d, key): r = dict(d) del r[key] return r
dict()
构造函数做一个浅拷贝 。 要进行深层复制,请参阅copy
模块 。
pop
突变字典。
>>>lol = {"hello":"gdbye"} >>>lol.pop("hello") 'gdbye' >>> lol {}
如果你想保留原件,你可以复制它。
我认为你的解决scheme是最好的办法。 但是如果你想要另一个解决scheme,你可以使用旧字典中的键创build一个新的字典,而不包括你指定的键,如下所示:
>>> 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'}
del语句就是你要找的东西。 如果你有一个叫做'bar'的键名为foo的字典,你可以像这样从foo中删除'bar':
del foo['bar']
请注意,这会永久性地修改正在操作的字典。 如果你想保留原来的字典,你必须事先创build一个副本:
>>> 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
d = {1: 2, '2': 3, 5: 7} del d[5] print 'd = ', d
结果:d = {1:2,'2':3}
只需调用del d ['key']。
然而,在生产中,检查d中是否存在“钥匙”总是一个好习惯。
if 'key' in d: del d['key']
>>> def delete_key(dict, key): ... del dict[key] ... return dict ... >>> test_dict = {'one': 1, 'two' : 2} >>> print delete_key(test_dict, 'two') {'one': 1} >>>
这不会做任何error handling,它假定关键是在字典中,你可能想先检查并raise
如果没有
不,没有别的办法
def dictMinus(dct, val): copy = dct.copy() del copy[val] return copy
但是,经常创build只有轻微改动的字典的副本可能不是一个好主意,因为这会导致相对较大的内存需求。 logging旧字典通常会更好(如果有必要的话),然后修改它。
很好的单行检查键是否存在,删除它,返回值,或默认值:
ret_val = ('key' in body and body.pop('key')) or 5
这里有一个顶级的devise方法:
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')
我将字典和我想要的密钥传入我的函数,validation它是否是字典,如果键是好的,并且如果两者都存在,则从字典中删除值并打印出左边的。
输出: {'B': 55, 'A': 34}
希望有所帮助!
有很多很好的答案,但我想强调一下。
您可以使用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'`
你必须照顾这个:
通过捕获exception:
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()
来获取被删除键的值,否则你可以提供任何东西,不需要。 虽然可能是因为pop()
是一个具有自己的复杂function而导致开销的函数,所以in
检查中使用del
会稍微快一点 。 通常情况并非如此,所以使用默认值的pop()
就足够了。
至于主要问题,你将不得不复制你的字典,保存原来的字典,并有一个新的没有被删除的关键。
这里的其他一些人build议用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}
这是另一个使用列表理解的变体:
original_d = {'a': None, 'b': 'Some'} d = dict((k,v) for k, v in original_d.iteritems() if v) # result should be {'b': 'Some'}
该方法是基于这个职位的答案: 有效的方法来从字典中删除空string的键
下面的代码片段将帮助你绝对,我已经在每一行添加评论,这将有助于你了解代码。
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}