Python列表值变更/变异

时间:2016-04-13 16:10:28

标签: python

我在这里运行了这个简单的代码,用于项目Euler问题31。

不需要欧拉Q;我只是想知道,为什么我的列表值会发生变异,即这是打印许多[2.0,2.0,2.0,2.0,2.0]列表的列表。

coins = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0]


perms = []
def check(c):
    if sum(c) == 2:
        print c, "lol", sum(c)
        perms.append(c)
    return perms

c = [0] * 5
for c[0] in coins:
    for c[1] in coins:
        for c[2] in coins:
            for c[3] in coins:
                for c[4] in coins:
                    check(c)

print perms

由于某种原因,这不起作用,输出是

[[2.0, 2.0, 2.0, 2.0, 2.0], [2.0, 2.0, 2.0, 2.0, 2.0]...]

perms = []
for c1 in coins:
    for c2 in coins:
        for c3 in coins:
            for c4 in coins:
                for c5 in coins:
                    if c1+c2+c3+c4+c5 == 2:
                        print c1,c2,c3,c4,c5
                        perms.append([c1,c2,c3,c4,c5])


print perms

然而,这个有效,输出是

[[0.1, 0.2, 0.2, 0.5, 1.0], [0.1, 0.2, 0.2, 1.0, 0.5], [0.1, 0.2, 0.5, 0.2, 1.0],[0.1, 0.2, 0.5, 1.0, 0.2], [0.1, 0.2, 1.0, 0.2, 0.5], [0.1, 0.2, 1.0, 0.5, 0.2],[0.1, 0.5, 0.2, 0.2, 1.0], [0.1, 0.5, 0.2, 1.0, 0.2]...]

两者有什么区别?

而且,我如何缩短我的代码,也许是一个递归函数? 因此,不是硬币中的c1,硬币中的c2等等,我只需要一个或两个循环来完成同样的工作。

2 个答案:

答案 0 :(得分:1)

问题是<{1}}在添加到c后仍然会被修改。您可以将副本传递给perms,然后它似乎可以正常工作。

check
顺便说一下,我甚至不知道c = [0] * 5 for c[0] in coins: for c[1] in coins: for c[2] in coins: for c[3] in coins: for c[4] in coins: check(c[:]) # c[:] creates a copy of c 是有效的Python语法...

此外,您可能需要查看for c[1] in coins,特别是productpermutationscombinationscombinations_with_replacement

递归函数看起来大致如下:

itertools

然而,这也似乎太慢,无法获得所有硬币组合。

答案 1 :(得分:1)

@tobias_k表示,在这种情况下,combinations_with_replacement可以使用来自permutations的{​​{1}}:

itertools

注意:如果您在此情况下使用列表,则应重复删除或以其他方式检查。