0

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?

user2685079
  • 104
  • 9

2 Answers2

4

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
Jayanth Koushik
  • 9,476
  • 1
  • 44
  • 52
2

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.

Alfe
  • 56,346
  • 20
  • 107
  • 159