New submission from Jason R. Coombs <jaraco at jaraco.com>:
In `whatsnew/3.0.html`, there is little said about the map builtin:
map() and filter() return iterators. If you really need a list, a quick fix is e.g. list(map(...)), but a better fix is often to use a list comprehension (especially when the original code uses lambda), or rewriting the code so it doesn’t need a list at all. Particularly tricky is map() invoked for the side effects of the function; the correct transformation is to use a regular for loop (since creating a list would just be wasteful).
This suggests that all one must do to port to Python 3 is wrap map in list, and in fact this is what the 2to3 fixers do, when in fact, map is semantically different in how it handles arguments of different lengths. Consider the following.
def to_tuple(*args):
return args
print(list(map(to_tuple, [1,2,3], [4,5,6,7])))
On Python 2, this code outputs:
[(1, 4), (2, 5), (3, 6), (None, 7)]
On Python 3, this code outputs:
[(1, 4), (2, 5), (3, 6)]
I suggest three fixes (in order of importance):
1) Document the difference in whatsnew/3.0.html.
2) Describe how one should port code of this usage to 3.0.
3) Incorporate the porting in the 2to3 fixer (if possible).
If no one objects, I'll begin on (1). Does anyone have any suggestions for a clean approach to (2)?
----------
assignee: docs at python
components: 2to3 (2.x to 3.0 conversion tool), Documentation
keywords: easy
messages: 141470
nosy: docs at python, jason.coombs
priority: normal
severity: normal
status: open
title: map semantic change not documented in What's New
type: behavior
versions: Python 3.1, Python 3.2, Python 3.3
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue12666>
_______________________________________