Unexpected list comprehension behaviour in Python
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Puzzle3
--
Chapters
00:00 Question
02:23 Accepted answer (Score 15)
02:56 Answer 2 (Score 4)
03:50 Thank you
--
Full question
https://stackoverflow.com/questions/2256...
Question links:
[Jeremy Hylton's blog post]: http://www.python.org/~jeremy/weblog/040...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #listcomprehension #languageimplementation
#avk47
    --
Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Puzzle3
--
Chapters
00:00 Question
02:23 Accepted answer (Score 15)
02:56 Answer 2 (Score 4)
03:50 Thank you
--
Full question
https://stackoverflow.com/questions/2256...
Question links:
[Jeremy Hylton's blog post]: http://www.python.org/~jeremy/weblog/040...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #listcomprehension #languageimplementation
#avk47
ACCEPTED ANSWER
Score 15
The problem is that with return self.display you return a reference to this list (not a copy). So what you end up with is a list where each element is a reference to self.display. To illustrate, look at the following:
>>> a = [1,2]
>>> b = [a,a]
>>> b
[[1, 2], [1, 2]]
>>> a.append(3)
>>> b
[[1, 2, 3], [1, 2, 3]]
You probably want to use something like return self.display[:].
ANSWER 2
Score 4
Mind if i refactor this a bit?
def digit(n):
    for i in itertools.count():
        yield (i%n+1, not i%n)
But actually you don't need that one, if you implement the whole thing as a simple iterator:
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))
If you want to get rid of the print (debugging, is it?), go with a while-loop.
This incindentally also solves your initial problem, because reversed returns a copy of the list.
Oh, and it's zero-based now ;)