Issue
Since there is some behavior difference in map
(especially with three arguments between Python 2 and Python - Python 2 vs Python 3 - Difference in map behavior with three arguments?), I was trying to be "safe" by using from past.builtins import map
so that my functionality is intact. But it doesn't seem to be so?
Here is a Python 2 code:
map(lambda x: [x], [1, 2])
which gives:
[[1], [2]]
Here is the Python 3 code which I am expecting to behave the same way, but does not:
from past.builtins import map
map(lambda x: [x], [1, 2])
gives:
[1, 2]
Surprisingly the new map
works as expected:
from builtins import map # Not needed if you didn't evaluate the above code.
list(map(lambda x: [x], [1, 2]))
Is there a reason why past.builtins
's map
behaves like this? Is this a bug?
Looks like there are some problems in getting the Python 2 map
behavior using past.builtins
module as mentioned in the source code comments.
Solution
This is an error in their implementation of map
. Here is their code for it:
def oldmap(func, *iterables):
"""
map(function, sequence[, sequence, ...]) -> list
Return a list of the results of applying the function to the
items of the argument sequence(s). If more than one sequence is
given, the function is called with an argument list consisting of
the corresponding item of each sequence, substituting None for
missing values when not all sequences have the same length. If
the function is None, return a list of the items of the sequence
(or a list of tuples if more than one sequence).
Test cases:
>>> oldmap(None, 'hello world')
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> oldmap(None, range(4))
[0, 1, 2, 3]
More test cases are in past.tests.test_builtins.
"""
zipped = itertools.zip_longest(*iterables)
l = list(zipped)
if len(l) == 0:
return []
if func is None:
result = l
else:
result = list(starmap(func, l))
# Inspect to see whether it's a simple sequence of tuples
try:
if max([len(item) for item in result]) == 1:
return list(chain.from_iterable(result))
# return list(flatmap(func, result))
except TypeError as e:
# Simple objects like ints have no len()
pass
return result
The error is where it says:
# Inspect to see whether it's a simple sequence of tuples
In their implementation, if the callable returns a list of objects with a len
of one then those are "unpacked" and a flattened list is returned. I'm not sure where this comes from though, since, as far as I know, Python 2 did not do this, even for tuples:
# Python 2
print(map(lambda x: (x,), [1, 2]))
# [(1,), (2,)]
There seems to be an open issue about it in the library code repository, if you want to follow on that.
Answered By - jdehesa
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.