The, afaik, respuesta completa y correcta.
for
, tanto en bucles como en listas de comprensión, llamadas iter()
en X
. iter()
devolverá un iterable si X
tiene un método __iter__
o un método __getitem__
. Si implementa ambos, se usa __iter__
. Si ninguno de los dos tiene TypeError: 'Nothing' object is not iterable
.
Esto implementa un __getitem__
:
class GetItem(object):
def __init__(self, data):
self.data = data
def __getitem__(self, x):
return self.data[x]
Uso:
>>> data = range(10)
>>> print [x*x for x in GetItem(data)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Este es un ejemplo de la aplicación de __iter__
:
class TheIterator(object):
def __init__(self, data):
self.data = data
self.index = -1
# Note: In Python 3 this is called __next__
def next(self):
self.index += 1
try:
return self.data[self.index]
except IndexError:
raise StopIteration
def __iter__(self):
return self
class Iter(object):
def __init__(self, data):
self.data = data
def __iter__(self):
return TheIterator(data)
Uso:
>>> data = range(10)
>>> print [x*x for x in Iter(data)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Como ve, necesita ambos implementar un iterador, y __iter__
que devuelve el iterador.
Puedes combinarlos:
class CombinedIter(object):
def __init__(self, data):
self.data = data
def __iter__(self):
self.index = -1
return self
def next(self):
self.index += 1
try:
return self.data[self.index]
except IndexError:
raise StopIteration
Uso:
>>> well, you get it, it's all the same...
Pero entonces sólo puede tener un iterador funcionando al mismo tiempo. bien, en este caso, usted podría hacer esto:
class CheatIter(object):
def __init__(self, data):
self.data = data
def __iter__(self):
return iter(self.data)
Pero eso es hacer trampa, porque se acaba de volver a utilizar el método de list
__iter__
. Una forma más fácil es usar el rendimiento, y hacer __iter__
en un generador:
class Generator(object):
def __init__(self, data):
self.data = data
def __iter__(self):
for x in self.data:
yield x
Esta última es la forma en que yo recomendaría. Fácil y eficiente
Tenga en cuenta que la palabra clave "in" se usa en dos contextos distintos en Python. Hay iteraciones (con el teclado "para") y hay contextos booleanos/condicionales (a veces con "si" o "mientras"). Este último recurre a los métodos __contains__ para sus objetos. –