Je crois que je suis mordu par une combinaison de règles de portée imbriquées et de compréhensions de listes. Jeremy Hylton's blog post est suggestive sur les causes, mais je ne comprends pas vraiment la mise en œuvre de CPython assez bien pour comprendre comment contourner cela.Comportement de compréhension de liste inattendu en Python
Voici un exemple (trop compliqué?). Si les gens en ont une version plus simple, j'aimerais l'entendre. Le problème: les compréhensions de liste utilisant next() sont remplies avec le résultat de la dernière itération.
modifier: Le problème:
ce qui se passe exactement cela, et comment puis-je résoudre ce problème? Dois-je utiliser une norme pour la boucle? Il est clair que la fonction s'exécute le nombre correct de fois, mais la compréhension de la liste se termine par la valeur finale au lieu du résultat de chaque boucle.
Quelques hypothèses:
- générateurs?
- remplissage paresseux de la compréhension de la liste?
Code
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)]
SORTIE
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
Je suis désolé mais quelle est la question? –
Édité, pour plus de clarté. –