#python
#python
Вопрос:
Я хочу выполнить итерацию словаря, проверить значение и удалить элементы, соответствующие определенным значениям.
Пример
d = {1, 1, 2, 1, 4, 5}
for i in d:
if i == 1:
del i
Но мы знаем, что делать это опасно, поскольку список обновляется во время итерации. Какой чистый способ сделать это в Python?
Комментарии:
1. Я полагаю, вы имеете в виду
d = [1,1,2,1,4,5]
(т. Е. скобки, а не фигурные скобки)?2. почему это получает отрицательный результат. Я новичок в Python и хотел бы знать, как это сделать?
3. Потому что в вашем вопросе задается вопрос о dictionary, но ваш код не имеет допустимого синтаксиса для dictionary и описывает операцию, которая является бессмысленной для словаря.
4. Даже игнорируя эту проблему, ваш пример ничего не делает, кроме перебора коллекций и (бессмысленно) удаления переменной итерации. Вам следует пересмотреть свое понимание переменных и
del
. Тем не менее, вопрос актуален.
Ответ №1:
Если k
— это ваш словарь, вы можете сделать
k = {x:v for x,v in k.iteritems() if x != 1}
Для 2.7 и 3.0
Для чего-либо более старого вы можете сделать
k = dict((x,v) for x,v in k.iteritems() if x!=1)
Комментарии:
1. Примечание: Поддерживается только в Python 3.X и 2.7 .
2. Спасибо. Я обновил его, чтобы включить что-то для более старых версий Python.
Ответ №2:
Я бы рекомендовал вам использовать встроенную filter
функцию, поскольку так более понятно, что будет сделано со списком. Также filter
работает с любым итерируемым: последовательностью, контейнером или итератором.
Вот пример того, как работать с функцией
In [2]: d = [1,1,2,1,4,5]
In [3]: filter(lambda x: (x!=1), d)
Out[3]: [2, 4, 5]
Вместо лямбда-выражения вы можете передать имя другой функции, которая будет использоваться для фильтрации данных из списка.
Документация по filter
доступна по адресу http://docs.python.org/library/functions.html#filter
Также обратите внимание, что filter
это хорошо известно в мире функционального программирования и использует мощные концепции, поэтому вы можете найти его на многих других языках даже с другой парадигмой.
Комментарии:
1.
filter
не очень по-питоновски. Вместо этого было бы лучше использовать понимание списка.2. @NoufalIbrahim Я мог бы написать что-то подобное
[el for el in d if el != 1]
, но это будет работать только со списками, а не с кортежами, например. Также обратите внимание, что фрагмент кода сfilter
функцией поймет больше программистов, и будет проще перенести программу, например, на другой язык.3. Почему это не будет работать для кортежей? Это также поддерживает протокол iterator. Ваш второй пункт на самом деле неверен. Фильтр с помощью лямбда-выражения в Python работает намного медленнее, а преимуществ переносимости и удобочитаемости недостаточно, чтобы компенсировать плохой стиль.
4. @NoufalIbrahim Дай мне посмотреть. Если я буду использовать
filter
подход, он будет работать следующим образом: codepad.org/gLKtSBT7 Мне не нужно ничего менять, чтобы фильтровать кортежи (иfilter
вернет кортеж вместо списка). Как я могу достичь этого, используя понимание списка? Я попробовал и получил это codepad.org/yi327lgN , поэтому для фильтрации кортежа мне нужно изменить код фильтрации (использовать что-то вродеtuple([x for x in d if x!=1])
)5. @NoufalIbrahim также меня не волнует, насколько медленными являются лямбды в Python, пока вся программа не будет работать хорошо. И даже в случае некоторых проблем с производительностью я сначала использую profiler вместо того, чтобы пытаться реализовать некоторые преждевременные оптимизации.
Ответ №3:
for j in range(len(d)-1,-1,-1):
if d[j] == 1:
del d[j]
Комментарии:
1. Это работает для списков, но является уродливым, неочевидным, не распространяется на непоследовательности (словари, наборы и т.д.) И Редко требуется.
2. Согласен.
for i in range(len(something))
это почти всегда плохой знак.
Ответ №4:
Хотя обычно я бы просто создал новый словарь (см. Ответ Нуфаля Ибрагима), вы можете безопасно модифицировать существующий словарь на месте, получив список ключей и выполнив итерацию по нему:
for k in d.keys():
if d[k] == 1:
del d[k]
Комментарии:
1. Примечание: Работает в Python 2.X, но в 3.X
d.keys()
возвращает представление словаря и завершается с ошибкойRuntimeError: dictionary changed size during iteration
. Используйтеlist(d.keys())
в 3.X.