In Python 2, a common (old, legacy) idiom is to use map to join iterators of uneven length using the form map(None,iter,iter,...) like so:
>>> map(None,xrange(5),xrange(10,12))
[(0, 10), (1, 11), (2, None), (3, None), (4, None)]
In Python 2, it is extended so that the longest iterator is the length of the returned list and if one is shorter than the other it is padded with None.
In Python 3, this is different. First, you cannot use None as an argument for the callable in position 1:
>>> list(map(None, range(5),range(10,12)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
OK -- I can fix that like so:
>>> def f(*x): return x
...
>>> list(map(f, *(range(5),range(10,12))))
[(0, 10), (1, 11)]
But now, I have a different problem: map returns the shortest iterator's length -- no longer padded with None.
As I port Python 2 code to Python 3, this is not a terrible rare idiom and I have not figured out an easy in place solution.
Unfortunately, the 2to3 tools does not pick this up -- unhelpfully suggesting:
-map(None,xrange(5),xrange(10,18))
+list(map(None,list(range(5)),list(range(10,18))))
Suggestions?
Edit
There is some discussion of how common this idiom is. See this SO post.
I am updating legacy code written when I was still in high school. Look at the 2003 Python tutorials being written and discussed by Raymond Hettinger with this specific behavior of map being pointed out...
map(None,*(iter,iter))is not a common idiom. Have you heard ofitertools.izip_longest()? Does exactly what you described, but without gimmicks.mapdescribed is straight from the Python 2 documents, yeah -- it is not uncommon...map()works, but usingmap(None, *(iter, iter))in this case seems to be very unpythonic for me. Also, I also wonder, whymap(None,*(xrange(5),xrange(10,12)))and not more directmap(None, xrange(5), xrange(10,12))? Does exactly the same. Any reference that could prove it is pythonic? Guido's confirmation would be enough, or Raymond Hettinger's, or part of Python's docs would do.mapin Python 2. Google 'python join list of different lengths' Some of the older answers use map.zipandzip_longest, which are far more understandable IMO.