Как избежать ошибки" RuntimeError: словарь изменил размер во время итерации"?
Я проверил все другие вопросы с той же ошибкой, но не нашел полезного решения =/
у меня есть словарь из списка:
d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
в котором некоторые значения пусты. В конце создания этих списков я хочу удалить эти пустые списки перед возвращением моего словаря. Тока я пытаюсь сделать это следующим образом:
for i in d:
if not d[i]:
d.pop(i)
однако, это дает мне ошибку времени выполнения. Я знаю, что вы не можете добавить/удалить элементы в словарь во время итерации по нему...как же тогда это обойти?
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]
Comments