Unexpected list comprehension behaviour in Python
--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Over a Mysterious Island
--
Chapters
00:00 Unexpected List Comprehension Behaviour In Python
01:35 Accepted Answer Score 15
01:59 Answer 2 Score 4
02:37 Thank you
--
Full question
https://stackoverflow.com/questions/2256...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #listcomprehension #languageimplementation
#avk47
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Over a Mysterious Island
--
Chapters
00:00 Unexpected List Comprehension Behaviour In Python
01:35 Accepted Answer Score 15
01:59 Answer 2 Score 4
02:37 Thank you
--
Full question
https://stackoverflow.com/questions/2256...
--
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 ;)