当密钥未知时从字典中删除项目

But*_*840 109 python dictionary

按值从字典中删除项目的最佳方法是什么,即项目的密钥未知时?这是一个简单的方法:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]
Run Code Online (Sandbox Code Playgroud)

还有更好的方法吗?在迭代它时从字典中变异(删除项目)有什么问题吗?

N 1*_*1.1 120

dict.pop(key[, default])方法允许您在知道密钥后删除项目.如果它删除了该项,则返回键处的值,否则返回传递的值default.查看文档.

例:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}
Run Code Online (Sandbox Code Playgroud)

  • OP询问关键何时未知 (3认同)

Tim*_*ker 92

请注意,您当前正在测试对象标识(isTrue当两个操作数由内存中的同一对象表示时才返回- 对于两个与之比较相等的对象,情况并非总是如此==).如果您是故意这样做的话,那么您可以将代码重写为

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}
Run Code Online (Sandbox Code Playgroud)

但这可能不会做你想要的:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}
Run Code Online (Sandbox Code Playgroud)

所以你可能想要!=而不是is not.

  • 你可以在这里使用`some_dict.iteritems()`并将`for`和`if`语句放在不同的行上以便于阅读 (4认同)
  • 我相信在Python 2.7中添加了字典理解. (3认同)
  • 这是字典压缩吗?他们什么时候加入? (2认同)
  • @JF Sebastian:我在使用Python 3,而`iteritems`现在是`items`.在Python 2.7中,`iteritems()`确实更好. (2认同)

Kra*_*mar 52

a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']
Run Code Online (Sandbox Code Playgroud)


小智 42

delpop()之间的简单比较:

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)
Run Code Online (Sandbox Code Playgroud)

结果:

0.0329667857143
0.0451040902256
Run Code Online (Sandbox Code Playgroud)

所以,delpop()更快.

  • 但是,性能差异并不大,如果你想避免引发异常,你可以为``pop()``提供第二个参数(如上面的@ n-1-1所示) - 这不是一个选项对于``del``运算符. (6认同)

mit*_*ndi 7

items()返回一个列表,它是你正在迭代的列表,因此在循环中改变dict并不重要.如果你使用的话iteritems(),在循环中改变dict 会有问题,同样viewitems()在Python 2.7中也是如此.

我想不出有更好的方法可以通过值从字典中删除项目.


小智 7

我将构建一个需要删除的密钥列表,然后删除它们.它简单,高效,避免了同时迭代和改变字典的任何问题.

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]
Run Code Online (Sandbox Code Playgroud)