So an iterable is an object that you can get an iterator from. An iterator is an object with a next (Python 2) or __next__ (Python 3) method. Whenever you use a for loop, or map, or a list comprehension, etc. in Python, the next method is called automatically to get each item from the iterator, thus going through the process of iteration.
First I want to clarify, I'm NOT asking what is "iterator". This is how the term "iterable" is defined in Python's doc: iterable An object capable of returning its members one at a time.
Checking isinstance(obj, Iterable) detects classes that are registered as Iterable or that have an __iter__() method, but it does not detect classes that iterate with the __getitem__() method. The only reliable way to determine whether an object is iterable is to call iter(obj).
An Iterable is a simple representation of a series of elements that can be iterated over. It does not have any iteration state such as a "current element". Instead, it has one method that produces an Iterator. An Iterator is the object with iteration state. It lets you check if it has more elements using hasNext() and move to the next element (if any) using next(). Typically, an Iterable ...
If you want to be able to iterate ctr more than once, it needs to be a non-iterator iterable, where it returns a brand new iterator each time __iter__ is invoked. Trying to mix and match (an iterator that is implicitly reset when __iter__ is invoked) violates the protocols.
The for statement just defines how iterable and iterator are used. If you are mostly familiar with external iteration, it helps looking at iterable and iterator as well.
The iterable is also provided by the user, and for situations where a single pass is enough it will work with an iterator (e.g., created by a generator for simplicity). But it would be nice to safeguard against the case were a user provides only an iterator when multiple passes are needed.
For example if data is a value returned from a function, then make sure that function returns an iterable object (such as list, numpy ndarray, pandas DataFrame etc.). If data is the value returned from some API call, make sure to check that the request returned an iterable object.
I have an interface which returns java.lang.Iterable<T>. I would like to manipulate that result using the Java 8 Stream API. However Iterable can't "stream". Any idea how to use the Iterab...
The collections iterable is less likely to cause problems as a superclass. So in short, you should use the typing iterable in type annotations, but the collections iterable as a superclass.