Sunday, March 8, 2015

From 2 to 3 - Part 2

Repeating problem (task) that I encounter during migration from Python 2 to Python 3 (Part-2):

* iteritems in Python
Based on this stackoverflow question:

In Python 2.x - .items() returned a list of (key, value) pairs.
In Python 3.x, .items() is now an itemview object, which behaves different - so it has to be iterated over, or materialised... So, list(dict.items()) is required for what was dict.items() in Python 2.x. 

In Python 2.7:
common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())
Will give you a list of the common keys, but again, in Python 3.x - just use .keys() instead.
common_keys = list(dict_a.keys() & dict_b.keys())
Python 3.x has generally been made to be more "lazy" - i.e. map is now effectively itertools.imap, zip is itertools.izip, etc.

* 'module' object has no attribute 'urlencode'
It's about urllib. In Python 3.x Do
import urllib.parse
instead. urlencode is part of urllib.parse

* ImportError: cannot import name 'quote'
Again about urllib. Similar like problem above you can do
from urllib.parse import quote
For direct import

* dictionary changed size during iteration
It's a problem in Python 3, in short; use list...

as explained:
In Python 2.x calling keys makes a copy of the key that you can iterate over while modifying the dict:
for i in d.keys():
Note that this doesn't work in Python 3.x because keys returns an iterator instead of a list. Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:
for i in list(d):

No comments:

Post a Comment