0

I have a very strange worries, with this way:

for k, v in ((k, v) for k, v in mydict.iteritems() if v.update):
    print k
    del mydict[k]

I know perfectly well that we should not change the key of the dictionary during iteration. But I was expecting a "RuntimeError: dictionary changed size during iteration" and nothing. I sometimes get a value, sometimes nothing ...

Python v2.7.10 on Osx

Johaven
  • 3
  • 2
  • I modified my question because I just realize that this is the delete method that produces this result – Johaven Jan 08 '16 at 18:19
  • I don't exhibit the same behaviour - if anything gets deleted I get a runtime error. Obviously changing from `iteritems()` to `items()` would fix the issue in Py2.X – AChampion Jan 08 '16 at 18:25
  • I also tested your code here, changing the `v.update` because I don't know what kind of object you are using there, and I got a RuntimeError: dictionary changed size during iteration. I am using python 2.7 – Gabriel Ilharco Jan 08 '16 at 18:27
  • yes update is an attribue of object v (setted to True or False) – Johaven Jan 08 '16 at 18:29
  • http://stackoverflow.com/questions/5384914/how-to-delete-items-from-a-dictionary-while-iterating-over-it – mortymacs Jan 08 '16 at 18:29
  • you can use `mydict.items()` instead. – mortymacs Jan 08 '16 at 18:30

1 Answers1

0

Breaks for me:

>>> mydict = {'a':1, 'b':10}
>>> for k, v in ((k, v) for k, v in mydict.iteritems() if v > 5):
...     print k
...     del mydict[k]
b
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
...

Obviously changing it to items() fixes this issue:

>>> mydict = {'a':1, 'b':10}
>>> for k, v in ((k, v) for k, v in mydict.items() if v > 5):
...     print k
...     del mydict[k]
b
>>> mydict
{'a': 1}

But a condition inside the loop is cleaner:

>>> mydict = {'a':1, 'b':10}
>>> for k, v in mydict.items():
...     if v > 5:
...         print k
...         del mydict[k]
b
>>> mydict
{'a': 1}

Or a dict comprehension:

>>> mydict = {'a':1, 'b':10}
>>> {k: v for k, v in mydict.iteritems() if not v > 5}
{'a': 1}
AChampion
  • 29,683
  • 4
  • 59
  • 75