Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does map over an iterable return a one-shot iterable?

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
like image 318
Manuel Schmidt Avatar asked Mar 31 '17 06:03

Manuel Schmidt


People also ask

What does map () return in Python?

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.)

Does map return a generator?

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.

Is map faster than for loop Python?

Comparing performance , map() wins! map() works way faster than for loop. Considering the same code above when run in this ide.

Are maps iterable Dart?

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.


1 Answers

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.

like image 148
user2357112 supports Monica Avatar answered Nov 15 '22 04:11

user2357112 supports Monica