Creo que me está mordiendo una combinación de reglas anidadas de scoping y listas de comprensión. Jeremy Hylton's blog post es sugerente sobre las causas, pero realmente no entiendo la implementación de CPython lo suficiente como para encontrar la manera de evitar esto.Comportamiento de comprensión de lista inesperada en Python
Aquí hay un ejemplo (¿complicado?). Si la gente tiene uno más simple que lo demuestre, me gustaría escucharlo. El problema: las listas de comprensiones que usan next() se llenan con el resultado de la última iteración.
edición: El Problema:
exactamente lo que está pasando con esto, y cómo puedo solucionar esto? ¿Tengo que usar un bucle estándar para? Claramente, la función se está ejecutando la cantidad correcta de veces, pero las listas de comprensión terminan con el valor final en lugar del resultado de cada ciclo.
Algunas hipótesis:
- generadores?
- relleno perezoso de la lista de comprensiones?
código
import itertools
def digit(n):
digit_list = [ (x,False) for x in xrange(1,n+1)]
digit_list[0] = (1,True)
return itertools.cycle (digit_list)
>>> D = digit(5) >>> [D.next() for x in range(5)] ## This list comprehension works as expected [(1, True), (2, False), (3, False), (4, False), (5, False)]
class counter(object):
def __init__(self):
self.counter = [ digit(4) for ii in range(2) ]
self.totalcount=0
self.display = [0,] * 2
def next(self):
self.totalcount += 1
self.display[-1] = self.counter[-1].next()[0]
print self.totalcount, self.display
return self.display
def next2(self,*args):
self._cycle(1)
self.totalcount += 1
print self.totalcount, self.display
return self.display
def _cycle(self,digit):
d,first = self.counter[digit].next()
#print digit, d, first
#print self._display
self.display[digit] = d
if first and digit > 0:
self._cycle(digit-1)
C = counter()
[C.next() for x in range(5)]
[C.next2() for x in range(5)]
SALIDA
In [44]: [C.next() for x in range(6)] 1 [0, 1] 2 [0, 2] 3 [0, 3] 4 [0, 4] 5 [0, 1] 6 [0, 2] Out[44]: [[0, 2], [0, 2], [0, 2], [0, 2], [0, 2], [0, 2]] In [45]: [C.next2() for x in range(6)] 7 [0, 3] 8 [0, 4] 9 [1, 1] 10 [1, 2] 11 [1, 3] 12 [1, 4] Out[45]: [[1, 4], [1, 4], [1, 4], [1, 4], [1, 4], [1, 4]] # this should be: [[0,3],[0,4]....[1,4]] or similar
Lo siento pero ¿cuál es la pregunta? –
Editado, para mayor claridad. –