Reputation: 2489
Why does map
when called with an object which can be iterated over multiple times not return an object which can also be iterated multiple times? I think the latter is much more reasonable.
My use case is that I have a lot of data
, such that it can only be iterated over. map
is (in theory) perfect for operations on data
, since it is lazy. However in the following example I would expect that the length is both times the same.
iterable = [1,2,3,4] # this can be iterated repeatedly
m = map(lambda x:x**2, iterable) # this again should be iterable repeatedly
print(len(list(m))) # 4
print(len(list(m))) # 0
How can I map over an iterable structure and get an iterable structure back?
Edit: This is an example of how it imho should work, demonstrating the lazy evaluation:
def g():
print('g() called')
data = [g, g]
# map is lazy, so nothing is called
m = map(lambda g: g(), data)
print('m: %s' % len(list(m))) # g() is called here
print('m: %s' % len(list(m))) # this should work, but doesnt
# this imap returns an iterable
class imap(object):
def __init__(self, fnc, iterable):
self.fnc = fnc
self.iterable = iterable
def __iter__(self):
return map(self.fnc, self.iterable)
# imap is lazy, so nothing is called
im = imap(lambda g: g(), data)
print('im: %s' % len(list(im))) # g() is called here
print('im: %s' % len(list(im))) # works as expected
Upvotes: 8
Views: 687
Reputation: 280973
Why does map when called with an object which can be iterated over multiple times not return an object which can also be iterated multiple times?
Because there is no interface to tell whether an object can be iterated over repeatedly. map
has no way to tell whether the thing it's iterating over supports repeat iteration, and unless map
manages to determine this information somehow and invents an API to expose it to its users, map
users would have no way to tell whether their map
object supports repeat iteration.
Also, with repeat iteration comes the need to either repeat the function evaluations or cache the results (but if you're going to cache the results, why redesign map
to return an iterator at all?). Repeated function evaluations are inefficient, potentially dangerous, and usually not what users want. It's better to have users explicitly repeat the map
call or explicitly call list
if they want to iterate again.
It's simpler if map
objects are always just iterators.
Upvotes: 7