问题:当关键字不明时从字典中删除项目

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

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

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

What is the best way to remove an item from a dictionary by value, i.e. when the item’s key is unknown? Here’s a simple approach:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

Are there better ways? Is there anything wrong with mutating (deleting items) from the dictionary while iterating it?


回答 0

请注意,您当前正在测试对象的身份(isTrue当两个操作数由内存中的同一对象表示时才返回-与相等的两个对象并不总是这样==)。如果您故意这样做,则可以将代码重写为

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"}
>>> 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'}

所以您可能想要!=代替is not

Be aware that you’re currently testing for object identity (is only returns True if both operands are represented by the same object in memory – this is not always the case with two object that compare equal with ==). If you are doing this on purpose, then you could rewrite your code as

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

But this may not do what you want:

>>> 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'}

So you probably want != instead of is not.


回答 1

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}

The dict.pop(key[, default]) method allows you to remove items when you know the key. It returns the value at the key if it removes the item otherwise it returns what is passed as default. See the docs.’

Example:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

回答 2

a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']
a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']

回答 3

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)

结果:

0.0329667857143
0.0451040902256

因此,delpop()快。

A simple comparison between del and pop():

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)

result:

0.0329667857143
0.0451040902256

So, del is faster than pop().


回答 4

items()返回一个列表,而该列表正是您要迭代的列表,因此在此循环中更改dict并不重要。如果您使用的是iteritems()替代方法,则在循环中更改dict 是有问题的viewitems()在Python 2.7中同样如此。

我想不出一种更好的方法来按值从字典中删除项目。

items() returns a list, and it is that list you are iterating, so mutating the dict in the loop doesn’t matter here. If you were using iteritems() instead, mutating the dict in the loop would be problematic, and likewise for viewitems() in Python 2.7.

I can’t think of a better way to remove items from a dict by value.


回答 5

我将建立一个需要删除的密钥列表,然后将其删除。它简单,高效,并且避免了同时迭代和变异字典的任何问题。

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]

I’d build a list of keys that need removing, then remove them. It’s simple, efficient and avoids any problem about simultaneously iterating over and mutating the dict.

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]

回答 6

c是新字典,a是您的原始字典,{‘z’,’w’}是您要从a中删除的键

c = {key:a[key] for key in a.keys() - {'z', 'w'}}

另请检查:https : //www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html

c is the new dictionary, and a is your original dictionary, {‘z’,’w’} are the keys you want to remove from a

c = {key:a[key] for key in a.keys() - {'z', 'w'}}

Also check: https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html


回答 7

y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]
y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]

回答 8

正如您所建议的,在迭代时从字典中删除项目没有任何问题。注意多个线程同时使用同一字典,这可能会导致KeyError或其他问题。

当然,请参阅http://docs.python.org/library/stdtypes.html#typesmapping中的文档

There is nothing wrong with deleting items from the dictionary while iterating, as you’ve proposed. Be careful about multiple threads using the same dictionary at the same time, which may result in a KeyError or other problems.

Of course, see the docs at http://docs.python.org/library/stdtypes.html#typesmapping


回答 9

这就是我要做的。

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break

This is how I would do it.

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。