Как избежать ошибки" RuntimeError: словарь изменил размер во время итерации"?



Я проверил все другие вопросы с той же ошибкой, но не нашел полезного решения =/



у меня есть словарь из списка:



d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}


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



for i in d:
if not d[i]:
d.pop(i)


однако, это дает мне ошибку времени выполнения. Я знаю, что вы не можете добавить/удалить элементы в словарь во время итерации по нему...как же тогда это обойти?

1217   5  

5 ответов:

В Python 2.х вызов keys создает копию ключа, который можно перебирать при изменении dict:

for i in d.keys():

обратите внимание, что это не работает в Python 3.x потому что keys возвращает итератор, а не список.

другой способ-использовать list чтобы заставить сделать копию ключей. Это также работает в Python 3.x:

for i in list(d):

просто используйте понимание словаря, чтобы скопировать соответствующие элементы в новый dict

>>> d
{'a': [1], 'c': [], 'b': [1, 2], 'd': []}
>>> d = { k : v for k,v in d.iteritems() if v}
>>> d
{'a': [1], 'b': [1, 2]}

вам нужно только использовать "копировать":

на этом пути вы перебираете исходные поля словаря и на лету можете изменить нужный dict (d dict). Это работа над каждой версией python, так что это более ясно.

In [1]: d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

In [2]: for i in d.copy():
   ...:     if not d[i]:
   ...:         d.pop(i)
   ...:         

In [3]: d
Out[3]: {'a': [1], 'b': [1, 2]}

Я бы попытался избежать вставки пустых списков в первую очередь, но, как правило, использовать:

d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty

Если до 2.7:

d = dict( (k, v) for k,v in d.iteritems() if v )

или так:

empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
    del[k]

Для Python 3:

{k:v for k,v in d.items() if v}

Comments

    Ничего не найдено.