0

我希望将数字 n 的除数作为存储在第 n 个位置的主列表中的列表。例如长度为 11 的筛子,我想要 sieve[6] == [2,3,6](忽略 1)。我下面的代码不起作用,并以一种令人不快的方式让我感到惊讶:

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]

请问可以解释一下吗?

4

2 回答 2

4

考虑这个例子:

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

当您声明sieve为列表的产品时,每个单独的列表都是同一个对象,对其中的一个所做的更改会反映在所有列表中。所以你需要解决这个问题。

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

您当然可以通过使用列表推导来简化整个过程。

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
于 2014-03-07T08:57:16.137 回答
2

您拥有由 term 创建的相同数组的副本[[]] * 11。因此,如果您修改其中一个内部数组,则所有内容都以相同的方式进行修改。

例如,您可以通过某种方式创建一个独立数组的列表[ [] for i in range(11) ]

于 2014-03-07T08:57:23.707 回答