Python:在递归函数中使用追加 - 覆盖以前的元素



有人可以解释如何解决以下问题吗?我已经阅读了一些解释,但无法理解它......

提前非常感谢!

k = 2                  # number of possible values for each element, in this case 0 or 1
length = 3             # length of list
result = [0] * length  # initialise list
results = []
# generate permutations of list
def permutations(i, k, length):
    j = 0
    while j < k:
        result[i] = j
        if i == length - 1:
            print("Result: ", result)
            results.append(result)
            print("Results: ", results)
        else:
            permutations(i + 1, k, length)
        j += 1
permutations(0, k, length)

在输出下方。问题是列表中所有以前的元素都被覆盖了......

Result:  [0, 0, 0]
Results:  [[0, 0, 0]]
Result:  [0, 0, 1]
Results:  [[0, 0, 1], [0, 0, 1]]
Result:  [0, 1, 0]
Results:  [[0, 1, 0], [0, 1, 0], [0, 1, 0]]
Result:  [0, 1, 1]
Results:  [[0, 1, 1], [0, 1, 1], [0, 1, 1], [0, 1, 1]]
Result:  [1, 0, 0]
Results:  [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]
Result:  [1, 0, 1]
Results:  [[1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1]]
Result:  [1, 1, 0]
Results:  [[1, 1, 0], [1, 1, 0], [1, 1, 0], [1, 1, 0], [1, 1, 0], [1, 1, 0], [1, 1, 0]]
Result:  [1, 1, 1]
Results:  [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

您每次都附加相同的列表。通过该引用修改列表会将更改传播到列表对象所在的每个位置;这是相同的列表。

您应该改为追加浅表副本,以便引用result仅修改当前列表:

...
results.append(result[:])

否则,您可以在函数的开头创建一个新的列表对象,以便每个递归调用都获得自己的列表:

def permutations(i, k, length):
    result = []
    ...
我相信

将 results.append(result( 更改为 result.append(result[:]( 应该可以解决问题。这是因为列表的可变性

你实现的东西可以被描述为重复排列或笛卡尔积。

k ** length列表或元组可以通过这种方式生成。

与任何组合、排列或产品一样,迭代工具可以帮助您:

from itertools import product
k = 2                  # number of possible values for each element, in this case 0 or 1
length = 3             # length of list
print(list(product(range(k), repeat=length)))
#[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]

做!

最新更新