Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I wish to get divisors of number n as a list stored in a master list at nth position. For example the sieve of length 11, I want sieve[6] == [2,3,6] (ignoring 1). My code below does not work and surprises me in an unpleasant way:

sieve = [[]]*11

sieve[1] = [1]

for i in range(2,11):

    for j in range(i,11,i):

        sieve[j].append(i)

        print ("appended", i ," at sieve",j)
        # This check-print statement shows that it works fine until sieve is printed. 
print (sieve)

sieve[6] turns out to be : [2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10]

Can that be explained please?

share|improve this question
 
possible duplicate of Unexpected feature in a Python list of lists –  user2357112 yesterday
add comment

2 Answers

Consider this example:

>>> a = [[]] * 5
>>> a
[[], [], [], [], []]
>>> a[0].append(1)
>>> a
[[1], [1], [1], [1], [1]]

When you declare sieve as a product of lists, each of the individual lists is the same object and changes made to one are reflected across all. So you need to fix that.

sieve = [[] for _ in xrange(11)]

You can of course just simplify the whole process by using list comprehension.

sieve = [[], [1], [2]] + [[j for j in xrange(2, i) if i%j == 0] for i in xrange(3, 11)]  # 0, 1, and 2 are special cases
share|improve this answer
 
Thanks Jayanth! –  user2685079 yesterday
add comment

You have copies of the same array created by the term [[]] * 11. So if you modify one of the inner array, all are modified in the same way.

You can create a list of independent arrays by sth like [ [] for i in range(11) ] for example.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.