I recently read that one benefit of map in Python 3 was that it is lazy. That means, it is better to do
map(lambda x: x**2, range(10**100))
First, please note that range (xrange in Python 2) is a special case. It's not a simple generator, nor does it just return a list. It supports in operations as well, which is not a standard feature of iterables or iterators.
Consider that map(func, iterable) could be called on an infinite iterable, or an iterable where the process of fetching the next value is a time consuming process.
You'd need to be aware that your function might deal with these types of values, and make sure to use a lazy function, like itertools.imap otherwise. Since its basically impossible to determine that an iterator is infinite, even at runtime, shouldn't the builtin function behave correctly for the widest range of inputs?
Not every use-case requires random access, and those that do must fully instantiate the iterable or use another itertools function like islice.