All iterators are iterable, but not all iterations are iterators.
The only requirement for iteration is that it defines the __iter__() method, which returns an iterator:
For container objects, one method must be defined in order to support iteration:
container.__iter__()
Return the iterator object.
an iterator must follow an iterator protocol that has two requirements:
It has a __iter__() method that returns the object itself :
iterator.__iter__()
Return the iterator object itself.
It has a __next__() method, which returns the next element for each call and, after exhaustion, raises the StopIteration on each subsequent call :
As soon as the __next__() iterator method raises StopIteration , it should continue to do so on subsequent calls. Implementations that do not obey this property are considered violated.
These requirements mean that iterators never repeat and that you can always confirm that an iterable is an iterator (and therefore unique by definition), confirming that iter(obj) is obj is True :
def is_unrepeatable(obj): return iter(obj) is obj
However: since the only requirement for iterable is that iter(obj) returns some iterator, you cannot prove that it repeats. The iterable can define the __iter__() method, which returns an iterator with different behavior each time it calls: for example, it can return an iterator that iterates over its elements on the first call, but on subsequent calls returns an iterator that immediately raises StopIteration .
Such behavior would be strange (and annoying), but not forbidden. Here is an example of a non-repeatable iterative class that is not an iterator:
class Unrepeatable: def __init__(self, iterable): self.iterable = iterable self.exhausted = False def __iter__(self): if self.exhausted: return else: self.exhausted = True yield from self.iterable
>>> x = Unrepeatable([1,2,3]) >>> list(x) [1, 2, 3] >>> list(x) [] >>> iter(x) is x False >>>
I would not hesitate to call such a “fake iterator” misbehaving, and I cannot think of a situation when you find it in the wild, but, as shown above, this is possible.