Python Iterators: Part Seven

Python iteratorsThe map, zip and filter built-in functions also became iterators in Python 3.0, as did range. This conserves space, as the result list does not have to be produced all at once in memory. All three process iterables and return iterable results in Python 3.0. Unlike range, however, they are their own iterators, and once you step through the results, they are exhausted and you cannot have multiple iterators on their results.

The basic form of the map function is:

map(function, iterable, ...)

The built-in map function returns an iterator that applies a function to every item of an iterable, yielding the resulting iterator. If additional arguments are passed, the function specified as the first argument must take that many arguments and apply them to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For example:

>>> mylist = map(abs, (1, 2, -3))
>>> list(mylist)
[1, 2, 3]
>>> mylist

 <map object at 0x0000000004069D30>

>>> next(mylist)
1
>>> next(mylist)
2
>>> next(mylist)
3
>>> next(mylist)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in 
    next(mylist)
StopIteration

>>> for x in mylist:
	print(x)

In our for loop, the map iterator is empty, so no output is produced. To do that, we need to create a new iterator:

>>> mylist = map(abs, (-4, 5, -6))
>>> for x in mylist:
	print(x)
	
4
5
6
>>> list(map(abs, (-4, 5, -6)))
[4, 5, 6]

The zip built-in function, introduced in the previous article, returns iterators that work the same way:

>>> myzip = zip((1, 2, 3), (4, 5, 6))
>>> myzip


>>> list(myzip)
[(1, 4), (2, 5), (3, 6)]
>>> for pair in myzip:
	print(pair)  	# Exhausted after one pass

>>> myzip = zip((1, 2, 3), (4, 5, 6))
>>> for pair in myzip:
	print(pair)

(1, 4)
(2, 5)
(3, 6)

>>> myzip = zip((1, 2, 3), (4, 5, 6))
>>> next(myzip)
(1, 4)
>>> next(myzip)
(2, 5)

The filter built-in function also behaves in a similar way. It returns items in an iterable for which a passed-in function returns True:

>>> filter(bool, ['not null', '', 'abc', 1, 0, -1])

['not null', 'abc', 1, -1]

Like map and zip, filter both accepts an iterable to process and returns an iterable to generate results in Python 3.0.

External Links:

The map built-in function at docs.python.org
Python Iterators at Python Wiki
Python Iterator tutorial at bogotobogo.com