@aquibmir See the Python Glossary for the relevant definitions:
In a nutshell, an iterable is a composite object able to yield its elements in a for-loop. There are all kinds of iterable objects in Python, including strings, tuples, lists, dictionaries, and so on. On the other hand, objects like integers aren’t iterable because you can’t iterate over them in a loop.
An iterator is another type of object whose role is to hide the details of visiting the individual elements of an iterable. It’s straightforward to think of iterating over a sequence like a Python list because each element has an associated index. However, some iterables don’t keep their elements in any particular order. For example, sets, trees, graphs, and other data structures are organized differently in memory, yet they all behave the same when you iterate over them.
You can define your own iterable that hooks into the for-loop by implementing a few special methods in a custom class. If your iterable has a known length and is a sequence indexed by a numeric index or a mapping accessed by a hashable key, then you can implement these two special methods in your custom class:
class Iterable:
def __getitem__(self, key_or_index):
...
def __len__(self):
...
Otherwise, you can use a more generic iterator protocol by implementing the .__iter__()
special method instead:
class Iterable:
def __iter__(self):
return Iterator(...)
Moreover, if you’d like to support iteration in reversed order, i.e., when someone calls reversed()
on your iterable, then you can optionally add yet another special method:
class Iterable:
def __iter__(self):
return Iterator(...)
def __reversed__(self):
return ReversedIterator(...)
In both cases, you return a new instance of an iterator class, which will handle the iteration. Alternatively, when the iteration has a relatively simple logic, it’s customary to use a generator iterator instead of returning a new instance of a class:
class Iterable1:
def __iter__(self):
yield from self.items
class Iterable2:
def __iter__(self):
for item in self.items:
yield item
If you choose to define an iterator class, then it must implement at least the .__next__()
special method, which supplies the next element of the iterable. However, to comply with the iterator protocol, it should also implement the .__iter__()
method that returns itself:
class Iterator:
def __next__(self):
...
def __iter__(self):
return self
This makes the iterator iterable itself, which is mandatory if you want to use it with a for-loop, which always calls iter()
first, and then keeps calling next()
on the resulting iterator object. To test your iterable and the corresponding iterator, you can simulate a for-loop by calling these functions manually:
>>> class Iterable:
... def __init__(self, *elements):
... self.elements = elements
... def __iter__(self):
... return Iterator(self.elements)
>>> class Iterator:
... def __init__(self, elements):
... self.elements = elements
... self.index = -1
... def __next__(self):
... self.index += 1
... if self.index < len(self.elements):
... return self.elements[self.index]
... raise StopIteration
... def __iter__(self):
... return self
>>> iterable = Iterable("apple", "banana", "orange")
>>> iterator = iter(iterable)
>>> next(iterator)
'apple'
>>> next(iterator)
'banana'
>>> next(iterator)
'orange'
>>> next(iterator)
Traceback (most recent call last):
File "<input>", line 1, in <module>
next(iterator)
File "<input>", line 9, in __next__
raise StopIteration
StopIteration
To signal that all elements have been exhausted, an iterator must raise the StopIteration
exception. However, it’s optional since your iterator might be infinite, in which case it will never exhaust iterable’s elements.
Note that iterators are typically one-use only, which means that once they reach the last element in the iterable, they’re no longer useful. You must create a brand new iterator instance, which will point the first element in an iterable.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4