Comment éviter de "RuntimeError: dictionnaire changé de taille au cours d'une itération d'erreur"?
J'ai vérifié toutes les autres questions avec la même erreur encore trouvé aucune solution utile =/
J'ai un dictionnaire de listes:
d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
Dans lequel certaines valeurs sont vides. À la fin de la création de ces listes, je veux supprimer ces listes vides avant de retourner mon dictionnaire. Courant, j'essaie de le faire comme suit:
for i in d:
if not d[i]:
d.pop(i)
Cependant, cela me donne l'erreur d'exécution. Je suis conscient que vous ne pouvez pas ajouter/supprimer des éléments dans un dictionnaire lors de l'itération à travers elle...ce serait un moyen de contourner cela, alors?
5 réponses
En Python 2.x appelant keys
fait une copie de la clé que vous pouvez parcourir en modifiant le dict
:
for i in d.keys():
Notez que cela ne fonctionne pas en Python 3.x parce que keys
renvoie un itérateur au lieu d'une liste.
Une Autre façon est d'utiliser list
pour forcer une copie des clés pour être fait. Celui-ci fonctionne également en Python 3.x:
for i in list(d):
Il suffit D'utiliser la compréhension du dictionnaire pour copier les éléments pertinents dans un nouveau 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]}
Il vous suffit d'utiliser "copy":
De cette façon, vous parcourez les champs du dictionnaire d'origine et, à la volée, vous pouvez modifier le dict souhaité (d dict). C'est du travail sur chaque version de python, donc c'est plus clair.
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]}
J'essaierais d'éviter d'insérer des listes vides en premier lieu, mais, utiliserait généralement:
d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty
Si avant 2.7:
d = dict( (k, v) for k,v in d.iteritems() if v )
Ou tout simplement:
empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
del[k]