Удалить элемент из словаря, если его ключ неизвестен - PullRequest
109 голосов
/ 27 марта 2011

Каков наилучший способ удалить элемент из словаря по значению, т.е. когда ключ элемента неизвестен?Вот простой подход:

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

Есть ли лучшие способы?Что-то не так с изменением (удалением элементов) из словаря при его повторении?

Ответы [ 10 ]

121 голосов
/ 27 марта 2011

Метод 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}
92 голосов
/ 27 марта 2011

Имейте в виду, что в настоящее время вы проверяете идентичность объекта (is возвращает True, только если оба операнда представлены одним и тем же объектом в памяти - это не всегда так с двумя объектами, которые сравниваются равными ==). Если вы делаете это специально, то вы можете переписать свой код как

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.

52 голосов
/ 27 марта 2011
a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']
41 голосов
/ 07 февраля 2013

Простое сравнение между del и 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)

результат:

0.0329667857143
0.0451040902256

Итак, del быстрее, чем pop () .

7 голосов
/ 27 марта 2011

Я бы составил список ключей, которые нужно удалить, а затем удалил бы их.Это просто, эффективно и позволяет избежать любой проблемы, связанной с одновременным повторением и изменением слова.

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]
7 голосов
/ 27 марта 2011

items() возвращает список, и этот список итерируется, поэтому изменение значения в цикле здесь не имеет значения. Если бы вы использовали iteritems() вместо этого, поменять слово в цикле было бы проблематично , а также для viewitems() в Python 2.7.

Я не могу придумать лучшего способа удалить предметы из диктанта по значению.

2 голосов
/ 15 апреля 2018

c - новый словарь, a - ваш исходный словарь, {'z', 'w'} ключи, которые вы хотите удалить из

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

Также проверьте: https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html

1 голос
/ 29 мая 2014
y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]
0 голосов
/ 03 октября 2018

Вот как бы я это сделал.

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break
0 голосов
/ 27 марта 2011

Нет ничего плохого в удалении элементов из словаря во время итерации, как вы предложили. Будьте осторожны, когда несколько потоков используют один и тот же словарь одновременно, что может привести к KeyError или другим проблемам.

Конечно, смотрите документы на http://docs.python.org/library/stdtypes.html#typesmapping

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...