This post was flagged by the community and is temporarily hidden.
All iterators are iterables. But only some iterables are iterators.
(All dogs are animals. But only some animals are dogs.)
An iterable is any object which can be iterated over. If you can
run:
for item in obj:
pass
without an error, then obj
is an iterable. Iterables include things
like:
- strings
- sequences such as lists, tuples, range() objects
- dicts
- sets
- generators
- iterators
An iterator is a special kind of iterable. To be an iterator, an
object has to belong to a class that provides two special methods:
-
an
__iter__
method which returnsself
; -
a
__next__
method which returns the next value in the sequence.
Any iterable can be converted into an iterator by calling the iter()
built-in function:
seq = [1, 2, 4, 8, 16] # Lists are iterables.
it = iter(seq) # Returns a "list-iterator"
In this example, seq
has no __next__
method, so it is not an
iterator. If we call the next()
builtin, it will fail:
next(seq) # raises TypeError
But it
is an iterator. If we call iter() on it again, we get the same
object:
a = iter(it)
assert a is it # same object
and it has a __next__
method:
next(it) # returns 1
next(it) # returns 2
next(it) # returns 4
next(it) # returns 8
next(it) # returns 16
next(it) # raises StopIteration when nothing left
Remember, like all special dunder (“Double UNDERscore”) methods, you
should not call __iter__
and __next__
directly, you should call the
builtins iter() and next().