Jak uniknąć błędu "RuntimeError: dictionary changed size during iteration"?
Sprawdziłem wszystkie inne pytania z tym samym błędem, ale nie znalazłem pomocnego rozwiązania =/
Mam słownik list:
d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
, w którym niektóre wartości są puste. Na koniec tworzenia tych list chcę usunąć te puste listy przed zwróceniem mojego słownika. Obecnie próbuję to zrobić w następujący sposób:
for i in d:
if not d[i]:
d.pop(i)
To jednak powoduje błąd runtime. Zdaję sobie sprawę, że nie można dodawać/usuwać elementów w słowniku podczas iteracji przez to...jak można to obejść?
5 answers
W Pythonie 2.x wywołanie keys
tworzy kopię klucza, który można iterować podczas modyfikowania dict
:
for i in d.keys():
Zauważ, że to nie działa w Pythonie 3.x ponieważ keys
zwraca iterator zamiast listy.
Innym sposobem jest użycie list
, aby wymusić kopię kluczy, które mają być wykonane. Ten działa również w Pythonie 3.x:
for i in list(d):
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-11 19:16:43
Wystarczy użyć rozumienia słownika, aby skopiować odpowiednie elementy do nowego 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]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-13 20:38:00
Wystarczy użyć "copy":
W ten sposób można iterację nad oryginalnymi polami słownika i w locie można zmienić żądany dict(d dict). To praca nad każdą wersją Pythona, więc jest bardziej przejrzysta.
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]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-13 14:37:46
W pierwszej kolejności starałbym się unikać wstawiania pustych list, ale generalnie używałbym:
d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty
Jeśli przed 2.7:
d = dict( (k, v) for k,v in d.iteritems() if v )
Lub po prostu:
empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
del[k]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-13 20:42:10
Dla Pythona 3:
{k:v for k,v in d.items() if v}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 07:47:20