문제

나는 중첩 범위 규칙과 목록 이해력의 조합에 물린 것으로 생각합니다. 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)]

산출

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
도움이 되었습니까?

해결책

문제는 return self.display 당신은 a 참조 이 목록에 (사본이 아님). 따라서 당신이 끝내는 것은 각 요소가 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[:].

다른 팁

내가 이것을 조금 리팩터링한다면 신경 쓰나요?

def digit(n):
    for i in itertools.count():
        yield (i%n+1, not i%n)

그러나 실제로 모든 것을 간단한 반복자로 구현하면 다음과 같은 것이 필요하지 않습니다.

def counter(digits, base):
    counter = [0] * digits

    def iterator():
        for total in itertools.count(1):
            for i in range(len(counter)):
                counter[i] = (counter[i] + 1) % base
                if counter[i]:
                    break
            print total, list(reversed(counter))
            yield list(reversed(counter))

    return iterator()

c = counter(2, 4)
print list(itertools.islice(c, 10))

인쇄물을 제거하려면 (디버깅,입니까?) While-Loop로 가십시오.

이것은 또한 초기 문제를 해결합니다 reversed 목록의 사본을 반환합니다.

아, 그리고 지금은 제로 기반입니다;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top