Я знаю, что нужно безопасно удалить запись «ключ» из моего словаря d
, вы:
if d.has_key('key'):
del d['key']
Однако мне нужно безопасно удалить несколько записей из словаря. Я думал об определении записей в кортеже, так как мне нужно будет сделать это более одного раза.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
Однако мне было интересно, есть ли более умный способ сделать это?
python
dictionary
dublintech
источник
источник
key in d
он более питонический, чемd.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Вероятно, это будет более эффективно, только еслиentities_to_remove
будет «большой».Ответы:
Почему не так:
Более компактная версия была предоставлена маттборнски с использованием dict.pop ()
источник
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
и обойтиkey in dict
тест.источник
dict.pop()
исключает необходимость проверки наличия ключей. Превосходно..pop()
это плохо и непонятно, и предпочел бы принятый ответ этому.setdefault
. Если он реализован правильно (а я уверен, что это так), он выполняет только один поиск в хэш-картеdict
, а не два.Использование словосочетаний
где key1 и key2 должны быть удалены.
В приведенном ниже примере ключи «b» и «c» должны быть удалены, и он сохраняется в списке ключей.
источник
O(n)
. Вся операция состоит в томO(mn)
, гдеm
- количество ключей в слове иn
количество ключей в списке. Я предлагаю{key1, key2}
вместо этого использовать набор , если это возможно.решение использует
map
иfilter
функциипитон 2
питон 3
ты получаешь:
источник
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... в функции карты python 3.4 возвращает итераторdeque(map(...), maxlen=0)
чтобы не создавать список значений None; первый импорт сfrom collections import deque
Если вам также нужно получить значения для ключей, которые вы удаляете, это будет довольно хороший способ сделать это:
Конечно, вы все еще можете сделать это только для удаления ключей из
d
, но вы без необходимости создавали бы список значений с пониманием списка. Также немного непонятно использовать понимание списка только для побочного эффекта функции.источник
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
и так далее.Нашел решение с
pop
иmap
Результат этого:
Я ответил на этот вопрос так поздно только потому, что думаю, что в будущем это поможет, если кто-то будет искать то же самое. И это может помочь.
Обновить
Приведенный выше код выдаст ошибку, если ключ не существует в dict.
вывод:
источник
keys
не существуетd
- вам нужно сначала отфильтровать его.У меня нет проблем ни с одним из существующих ответов, но я был удивлен, не найдя этого решения:
Примечание: я наткнулся на этот вопрос, исходящий отсюда . И мой ответ связан с этим ответом .
источник
Почему нет:
Я не знаю, что вы имеете в виду под «умнее». Конечно, есть и другие способы, возможно, с пониманием словаря:
источник
в линию
источник
Некоторые временные тесты для cpython 3 показывают, что простой цикл for - самый быстрый способ, и он вполне читаем. Добавление функции также не вызывает особых накладных расходов:
Результаты timeit (10k итераций):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
Для небольших итераций выполнение этого «встроенного» было немного быстрее из-за накладных расходов на вызов функции. Но
del_all
он безопасен для ворса, его можно использовать повторно и быстрее, чем все конструкции понимания и сопоставления Python.источник
Я думаю, что использование того факта, что ключи можно рассматривать как набор, - лучший способ, если вы используете python 3:
Пример:
источник
Было бы неплохо иметь полную поддержку методов набора для словарей (а не того нечестивого беспорядка, который мы получаем с Python 3.9), чтобы вы могли просто «удалить» набор ключей. Однако, если это не так, и у вас есть большой словарь с потенциально большим количеством ключей, которые нужно удалить, вы можете узнать о производительности. Итак, я создал код, который создает что-то достаточно большое для значимых сравнений: матрица 100 000 x 1000, итого 10 000 000 элементов.
10 миллионов элементов и более - обычное дело для некоторых настроек. Сравнивая два метода на моем локальном компьютере, я вижу небольшое улучшение при использовании
map
иpop
, предположительно из-за меньшего количества вызовов функций, но оба метода на моем компьютере занимают около 2,5 с. Но это меркнет по сравнению со временем, необходимым для создания словаря в первую очередь (55 с) или включением проверок в цикле. Если это вероятно, лучше всего создать набор, который является пересечением ключей словаря и вашего фильтра:keys = cells.keys() & keys
В итоге:
del
он уже сильно оптимизирован, поэтому не беспокойтесь об его использовании.источник
Я опаздываю на это обсуждение, но для всех остальных. Решением может быть создание списка ключей как такового.
Затем используйте pop () в понимании списка или в цикле for, чтобы перебирать ключи и выскакивать по одному как таковые.
«Н / п» означает, что если ключ не существует, необходимо вернуть значение по умолчанию.
источник
new_dictionary
ужасно похоже на список;)