for_loop.py
for i in [0, 1, 2, 3, 4]:
print(i)
Quand tu cours
% python for_loop.py
0
1
2
3
4
for i in
Je veux savoir comment la chose derrière est utilisée.
(Dans le cas de l'exemple ci-dessus, il semble que les éléments de `` [0, 1, 2, 3, 4] '' soient extraits dans l'ordre.)
Voyons comment il est atteint en référence à l'erreur d'exécution
duck.py
class Duck(object):
pass
if __name__ == '__main__':
for i in Duck():
print(i)
Quand je le lance, je me fâche si ce n'est pas itérable
% python duck.py
Traceback (most recent call last):
File "duck.py", line 6, in <module>
for i in Duck():
TypeError: 'Duck' object is not iterable
__ iter__ ()
On m'a dit de le mettre en œuvre, alors je vais le mettre en œuvre. Mais retourne juste un objet vide
duck.py
class DuckIter(object):
def __init__(self):
pass
class Duck(object):
def __iter__(self):
return DuckIter()
if __name__ == '__main__':
for i in Duck():
print(i)
L'erreur a changé (un pas en avant!)
% python duck.py
Traceback (most recent call last):
File "duck.py", line 12, in <module>
for i in Duck():
TypeError: iter() returned non-iterator of type 'DuckIter'
`` next () ''Essayez de crier trois fois.
duck.py
class DuckIter(object):
def __init__(self):
self._count = 3
def next(self):
if self._count > 0:
self._count -= 1
return "quack"
raise StopIteration()
class Duck(object):
def __iter__(self):
return DuckIter()
if __name__ == '__main__':
for i in Duck():
print(i)
Plus d'erreurs lors de l'exécution
% python duck.py
quack
quack
quack
Le canard a sonné!
If it walks like a duck and quacks like a duck, it must be a duck https://ja.wikipedia.org/wiki/ダック・タイピング
L'objet lui-même détermine ce que l'objet peut faire (Indépendamment de l'héritage qu'ils ont)
Dans le cas de l'exemple précédent
`` next () ''.Cela nous a permis de tourner la boucle for:
for i in Duck():
print(i)
Cette notation est à peu près la même que ci-dessous
iter = Duck().__iter__()
while True:
try:
i = iter.next()
print(i)
except StopIteration:
break
En d'autres termes, le flux de traitement de la boucle for
Créons un objet avec un itérateur dans l'ordre inverse de la liste
>>> lst = [0, 1, 2, 3, 4]
>>> rev = RevList(lst)
>>> for r in rev:
... print(r)
...
4
3
2
1
0
Pointe:
`next ()` `méthode" avec
__iter__ ()
``
next () '' `` retourne à partir de la fin de la liste d'origineclass RevListIter(object):
def __init__(self, lst):
self._orig = lst
self._i = len(lst)
def next(self):
if self._i > 0:
self._i -= 1
return self._orig[self._i]
raise StopIteration()
class RevList(object):
def __init__(self, lst):
self._orig = lst
def __iter__(self):
return RevListIter(self._orig)
if __name__ == '__main__':
lst = [0, 1, 2, 3, 4]
rev = RevList(lst)
for r in rev:
print(r)
class RevList(object):
def __init__(self, lst):
self._orig = lst
def __iter__(self):
return self._orig[::-1].__iter__()
if __name__ == '__main__':
lst = [0, 1, 2, 3, 4]
rev = RevList(lst)
for r in rev:
print(r)
Créons un itérateur qui met au carré chaque élément d'une liste d'entiers
>>> lst = [0, 1, 2, 3, 4]
>>>pour moi dans quelque chose(lst):
... print(i)
...
0
1
4
9
16
>>> lst = [0, 1, 2, 3, 4]
>>> for i in [x*x for x in lst]:
... print(i)
...
0
1
4
9
16
>>> for i in (x*x for x in lst):
... print(i)
...
0
1
4
9
16
Les deux sont des solutions. Voyons la différence entre les deux.
notation
[f(x) for x in lst]
Exemple de code
list_comprehension.py
def f(x):
print("%d*%d" % (x, x))
return x*x
if __name__ == '__main__':
lst = [0, 1, 2, 3, 4]
x = [f(x) for x in lst]
print(type(x))
for i in x:
print(i)
Résultat d'exécution
% python list_comprehension.py
0*0
1*1
2*2
3*3
4*4
<type 'list'>
0
1
4
9
16
notation
(f(x) for x in lst)
Exemple de code
generator_expression.py
def f(x):
print("%d*%d" % (x, x))
return x*x
if __name__ == '__main__':
lst = [0, 1, 2, 3, 4]
x = (f(x) for x in lst)
print(type(x))
for i in x:
print(i)
Résultat d'exécution
% python generator_expression.py
<type 'generator'>
0*0
0
1*1
1
2*2
4
3*3
9
4*4
16
__iter__ ()
,
next () '' ``, iterable est terminé.Recommended Posts