ネストされたスコープ規則とリスト内包表記の組み合わせに悩まされていると思います。 Jeremy Hylton のブログ投稿は原因について示唆に富んでいますが、CPython の実装を十分に理解していないため、これを回避する方法を理解することができません。
これは(複雑すぎる?)例です。人々がそれをデモする簡単なものを持っているなら、私はそれを聞きたい. 問題: next() を使用したリスト内包表記は、最後の反復の結果で埋められます。
編集:問題:
これで正確に何が起こっているのですか?どうすれば修正できますか? 標準の for ループを使用する必要がありますか? 明らかに、関数は正しい回数実行されていますが、リスト内包表記は各ループの結果ではなく、最終的な値で終わります。
いくつかの仮説:
- 発電機?
- リスト内包表記の遅延充填?
コード
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 = 桁(5) >>> [D.next() for x in range(5)] ## このリスト内包表記は期待どおりに機能します [(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)]
出力
[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] 出力[44]: [[0, 2], [0, 2], [0, 2], [0, 2], [0, 2], [0, 2]] [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] 出力[45]: [[1, 4], [1, 4], [1, 4], [1, 4], [1, 4], [1, 4]] # これは [[0,3],[0,4]....[1,4]] または類似