Уведомления

Группа в Telegram: @pythonsu

#1 Май 4, 2013 19:46:30

WhiteTiger
Зарегистрирован: 2012-11-15
Сообщения: 31
Репутация: +  0  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

Всем привет. Возникла необходимость в цикле обойти словарь и удалить некоторые его элементы. Кандидаты на удаление обнаружаются с помощью условия внутри этого цикла. Вот банальный пример подобного кода:

myDict = {'a': 1, 'b': 2}
for k in myDict:
    if k == 'a':
        del myDict[k]
Третий питон, при запуске, ругается на то, что во время обхода словаря меняется его размер
RuntimeError: dictionary changed size during iteration
Можно ли как-то этого избежать? Со списками такой фокус проходит (удаляю элементы через .remove()). Хотелось бы и со словарями научиться это делать.

Офлайн

#2 Май 4, 2013 20:04:50

Romiss
От:
Зарегистрирован: 2011-11-01
Сообщения: 26
Репутация: +  4  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

myDict = {'a': 1, 'b': 2}
for k in myDict.keys():
    if k == 'a':
        del myDict[k]
print myDict



Офлайн

#3 Май 4, 2013 21:56:06

Yott
От: Санкт-Петербург
Зарегистрирован: 2013-01-14
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

Romiss , ваш фрагмент кода вызывает такой же протест

Офлайн

#4 Май 4, 2013 22:19:28

Romiss
От:
Зарегистрирован: 2011-11-01
Сообщения: 26
Репутация: +  4  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

Yott
Romiss , ваш фрагмент кода вызывает такой же протест
Да, вы правы в python 2.7 работает,а вот 3 выдает ошибку.



Офлайн

#5 Май 4, 2013 22:22:16

elisk
Зарегистрирован: 2013-04-09
Сообщения: 35
Репутация: +  7  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

Выше написанный код сработает во втором питоне. В третьем немного по-другому. Один из способов - через копию:

#-*- coding: utf-8 -*-
myDict = {'a': 1, 'b': 2}
Dict = myDict.copy()
for k in Dict.keys():
    if k == 'a':
        del myDict[k]
print("myDict: ", myDict)     # myDict:  {'b': 2}
print("Dict: ", Dict)             # Dict:  {'a': 1, 'b': 2}

Офлайн

#6 Май 4, 2013 22:24:14

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

for k in list(myDict.keys()):
    ...
И если проверки в коде так выглядят именно так
if key == 'a':
    ...
то логичнее было бы пробежаться по списку удаляемых ключей:
keys_to_delete = ['a', 'b', 'c']
for key in keys_to_delete:
    dct.pop(key, None)

Офлайн

#7 Май 4, 2013 22:44:21

elisk
Зарегистрирован: 2013-04-09
Сообщения: 35
Репутация: +  7  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

reclosedev
for k in list(myDict.keys()):
    ...

Скорей всего использование списков наилучший способ:
myDict = {'a': 1, 'b': 2}
for k in list(myDict.keys()):
    if k == 'a':
        myDict.pop(k)
print("myDict: ", myDict)  # myDict:  {'b': 2}

Отредактировано elisk (Май 4, 2013 22:45:52)

Офлайн

#8 Май 5, 2013 17:45:49

WhiteTiger
Зарегистрирован: 2012-11-15
Сообщения: 31
Репутация: +  0  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

Всем спасибо! Решал через создание копии. Думал что использовал костыль, а оказывается нет

Офлайн

#9 Май 6, 2013 05:35:36

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9885
Репутация: +  853  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

>>> myDict = {'a': 1, 'b': 2}
>>> for k in set(myDict):
...     if k == 'a':
...         del myDict[k]
... 
>>> myDict
{'b': 2}
>>>



Офлайн

#10 Май 6, 2013 10:42:41

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Удаление частей словаря в цикле

py.user.next
а в чем здесь выгода множеств в отличии от списка, кортежа?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version