What is the difference between an Iterator and Iterable?

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 returns self;

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