我相信我会被嵌套的范围规则和列表推导的某些组合所困扰. Jeremy Hylton的博客文章暗示了原因,但我并不完全理解CPython的实现,足以弄清楚如何解决这个问题.
这是一个(过于复杂的?)示例.如果人们有一个更简单的演示,我想听听它.问题:使用next()的列表推导用最后一次迭代的结果填充.
编辑:问题:
到底是怎么回事,我该如何解决这个问题?我是否必须使用标准循环?显然,该函数运行的次数正确,但列表推导最终得到的是最终值而不是每个循环的结果.
一些假设:
发电机?
懒惰填写列表理解?
码
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)]
OUTPUT
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
mweerden.. 15
问题是,return self.display
您返回对此列表的引用(而不是副本).所以你最终得到的是一个列表,其中每个元素都是self.display的引用.为了说明,请看以下内容:
>>> a = [1,2] >>> b = [a,a] >>> b [[1, 2], [1, 2]] >>> a.append(3) >>> b [[1, 2, 3], [1, 2, 3]]
你可能想要使用类似的东西return self.display[:]
.
问题是,return self.display
您返回对此列表的引用(而不是副本).所以你最终得到的是一个列表,其中每个元素都是self.display的引用.为了说明,请看以下内容:
>>> a = [1,2] >>> b = [a,a] >>> b [[1, 2], [1, 2]] >>> a.append(3) >>> b [[1, 2, 3], [1, 2, 3]]
你可能想要使用类似的东西return self.display[:]
.