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
map() function returns a map object(which is an iterator) of the results after applying the given function to each item of a given iterable (list, tuple etc.)
map() returns a map object, which is an iterator that yields items on demand. So, the natural replacement for map() is a generator expression because generator expressions return generator objects, which are also iterators that yield items on demand.
Comparing performance , map() wins! map() works way faster than for loop. Considering the same code above when run in this ide.
Iterating over the elements of a collection Since List is iterable, you're able to iterate over it. Not all Dart collections are iterables, though. Most notably, Map isn't.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With