Iterator & Iterable
iterator
- get next item (
__next__
) - no indexes needed (Don’t need to be Sequence type)
- consumable
iterable
- collections that implement iterator
Protocal
Python need to count on certain funcionality: __next__
、__iter__
、StopIteration
compare to sequence type
iteration can be more general than sequential indexing, we only need:
- a bucket of items: collection, container
- a way to get the next item, no need to care about ordering
- an exception to raise if there is no next item
try to custom an iterator ourselfs:
Why re-create?
Seperate the Collection from the iterator
Iterable object
- Maintaining the data of the collection is one object
- Created once
- implements
__iter__
, return a new iterator instance
Iterator object
- Iterating over that data should be another object
- throw away the iterator but don’t throw away the collection
- Created every time
- implements
__iter__
, return itself - implements
__next__
, return next item
iterable can be lazy
Caculate the next itme in an iterable until it’s actually requested
lazy evaluation
- often used in class properties
- properties of classes may not always populated when the object is created
- value of property only becomes known when the property is requested/deferred
infnite iterables
- itertools.cycle
Python Built-ins
- range: return iterable
- zip: return iterator
- enumerate: return iterator
- open: return iterator
- reversed: return iterator
The type is important. Iterator object can be only iter over once.
iter()
when iter
is called:
- Python first looks for
__iter__
, if not then: - look for
__getitem__
and create an iterator, if not then: - raise TypeError
Test it:
1 2 3 4 5 |
try: iter(obj) except TypeError: print('Not iterable ...') |
The __iter__
must return an iterator!
Iterating callable
iterator delegation
Example 1
Example 2