Search code examples
pythonpython-3.xpython-2to3

Why does 2to3 change mydict.keys() to list(mydict.keys())?


I'm looking at an output from 2to3 that includes this change:

-            for file_prefix in output.keys():
+            for file_prefix in list(output.keys()):

where output is a dictionary.

What is the significance of this change? Why does 2to3 do this?

How does this change make the code Python 3 compatible?


Solution

  • In Python 3, the .keys() method returns a view object rather than a list, for efficiency's sake.

    In the iteration case, this doesn't actually matter, but where it would matter is if you were doing something like foo.keys()[0] - you can't index a view. Thus, 2to3 always adds an explicit list conversion to make sure that any potential indexing doesn't break.

    You can manually remove the list() call anywhere that a view would work fine; 2to3 just isn't smart enough to tell which case is which.

    (Note that the 2.x version could call iterkeys() instead, since it's not indexing.)