我在这里运行了这个简单的代码,用于项目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等等,我只需要一个或两个循环来完成同样的工作。
答案 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
,特别是product
,permutations
,combinations
和combinations_with_replacement
。
递归函数看起来大致如下:
itertools
然而,这也似乎太慢,无法获得所有硬币组合。
答案 1 :(得分:1)
@tobias_k表示,在这种情况下,combinations_with_replacement
可以使用来自permutations
的{{1}}:
itertools
注意:如果您在此情况下使用列表,则应重复删除或以其他方式检查。