The built-in iter()
method in Python 2.2 and later hides a neat trick which is not
well-known. Typically iter()
is used to return an iterator from an iterable object:
i = iter(iterable_object)
next(i)
However, iter()
can also be used in an entirely different way. If you have a
function that you need to call multiple times until a particular value is returned, then
iter()
will let you wrap that function into a convenient iterator. To do this, pass
the function as the first argument, and the return value to end with as the second argument:
iter(repeated_function, stop_value)
For example, you could read a text file until you reached a certain text marker:
with open('file.txt') as f:
for line in iter(f.readline, '#~END_OF_IMPORTANT_TEXT'):
do_something(line)
One restriction is that the function passed to iter()
can't take any arguments.
You can use either a lambda expression, or functools.partial()
to "fill in" a
function's arguments before using it with iter()
. For example, here are two ways
you could read 4KB at a time from a source object that has a file-like read()
method:
# Using a lambda expression
for chunk in iter(lambda: some_source.read(4096), ''):
do_something(chunk)
# Using functools.partial()
from functools import partial
read_chunk = partial(some_source.read, 4096)
for chunk in iter(read_chunk, ''):
do_something(chunk)