python - Dictionary changed size during iteration - Code works in Py2 Not in Py3 -




i have following sample code:

k_list = ['test', 'test1', 'test3']  def test(*args, **kwargs):     k, value in kwargs.items():         if k in k_list:             print("popping k = ", k)             kwargs.pop(k, none)     print("remaining kwargs:", kwargs.items())  test(test='test', test1='test1', test2='test2', test3='test3') 

in python 2.7.13 prints expect , still has item left in kwargs:

('popping k = ', 'test') ('popping k = ', 'test1') ('popping k = ', 'test3') ('remaining kwargs:', [('test2', 'test2')]) 

in python 3.6.1, however, fails:

popping k =  test traceback (most recent call last):   file "test1.py", line 11, in <module>     test(test='test', test1='test1', test2='test2', test3='test3')   file "test1.py", line 5, in test     k, value in kwargs.items(): runtimeerror: dictionary changed size during iteration 

what need adjust maintain python 2 compatibility work correctly in python 3.6? remaining kwargs used later logic in script.

the reason works in python2.x because kwargs.items() creates list -- can think of snapshot of dictionary's key-value pairs. since snapshot, can change dictionary without modifying snapshot you're iterating on , ok.

in python3.x, kwargs.items() creates view dictionary's key-value pairs. since view, can no longer change dictionary without changing view. why error in python3.x

one resolution work on both python2.x , python3.x create snapshot using list builtin:

for k, value in list(kwargs.items()):     ... 

or, alternatively, create snapshot copying dict:

for k, value in kwargs.copy().items():     ... 

this work. in unscientific experiement did in interactive interpreter, first version fair amount faster second on python2.x. note whole thing inefficient on python2.x because you'll creating addition copy of (either list or dict depending on version reference). based on other code, doesn't of concern. if is, can use six compatibility:

for k, value in list(six.iteritems(kwargs)):     ... 




wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -

python - Read npy file directly from S3 StreamingBody -