Wedge
If I have a list l=['a','b','c','d','e '], how can I get the contents of the list?
First of all, I can use index value l[0]. Second, can we still use for loop to get value?
Have you ever thought about it carefully? There is a subtle difference between index value and for loop value.
If you use the index value, you can get the value at any position, provided you know where the value is.
If we use the for loop to get values, we can get each value. We don't need to care about the position of each value, because we can only get values in sequence, and we can't skip any value to get other values directly.
But have you ever thought about why we can use the for loop to get values?
How does the for loop work internally?
iterator
for loop in python
To understand what's going on with the for loop in python, let's start from a code point of view.
First, we loop for a list.
for i in [1,2,3,4]:
print(i)
The above code is certainly no problem, but let's try to loop a number 1234 in another case
for i in 1234
print(i)
//Result:
Traceback (most recent call last):
File "test.py", line 4, in <module>
for i in 1234:
TypeError: 'int' object is not iterable
Look, it's wrong! What's wrong with the report? "TypeError: 'int' object is not iterable", which means int type is not an iterable. What is this iterable?
If you don't know what is iterable, we can turn to the dictionary and get a Chinese explanation first. Although you may not know it after translation, it doesn't matter. I will take you step by step to analyze it.
Iterative and iterative protocols
What is iteration
Now, we've got a new clue, a concept called "iterative.".
First of all, we analyze the error report. It seems that the reason why 1234 can't be for loop is that it can't be iterated. So if it's "iterative," it should be able to be looped for.
We know that strings, lists, tuples, dictionaries, and sets can all be for loops, indicating that they are all iterative.
How can we prove that?
from collections import Iterable
l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
In combination with the phenomenon that we use for loop value, and then understand it literally, in fact, iteration is what we just said, which is called iteration, that is, we can extract the data in a dataset "one by one".
Iterative protocol
We are now analyzing the reasons from the results. What can be looped by for is "iterative". But if we are thinking about it, how can for know who is iterative?
If we write a data type ourselves, and hope that things in this data type can also be retrieved one by one using for, then we must meet the requirements of for. This requirement is called "agreement".
The requirements that can be satisfied by iteration are called iterative protocols. The definition of iterative protocol is very simple, that is, it implements the "iter" method internally.
Next, let's verify:
print(dir([1,2]))
print(dir((2,3)))
print(dir({1:2}))
print(dir({1,2}))
Result['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index'] ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']