我在这里产生了6个职位的两种可能结果的所有可能安排:
paths = list(it.product([['ax','r',[],0], ['ax','l',[],0]], repeat=6))
它应该产生的是:
(['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax',
'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0])
这是列表中包含所有结果的一个元素。
我想根据重复模式改变'ax'字符串
'yp', 'p', 'xp'
为此,我写了这样的话:
for path in paths:
axis = 1
for axis_slice in path:
if(axis%3 == 1):
axis_slice[0] = 'yp'
print(axis_slice[0])
elif(axis%3 == 2):
axis_slice[0] = 'p'
print(axis_slice[0])
elif(axis%3 == 0):
axis_slice[0] = 'xp'
print(axis_slice[0])
axis+=1
print("axis: "+str(axis))
print(path)
但结果是这样的:
(['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0])
然而上面这些行中的印刷语句向我显示它们被正确分配,但是在一个'级别'后面的分配('yp','p','xp')分叉
yp
p
xp
yp
p
xp
axis: 7
(['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0], ['xp', 'r', [], 0])
这种行为是如何产生的?为什么它在内循环中不可见但在外循环中不可见?我觉得它可能与评估的顺序和元组/列表的打包方式有关。
如何实现目标输出?
答案 0 :(得分:1)
您的问题是path
中每个paths
内的所有列表成员都是同一个对象。要自己验证 - 请尝试:
import itertools as it
paths = list(it.product([['ax','r',[],0], ['ax','l',[],0]], repeat=6))
for path in paths:
print([id(p) for p in path])
这将打印路径中每个列表的唯一标识符。您将看到只有两个ID - 您传递给it.product
的原始两个列表的ID。
因此,例如,如果你采取第一条路径:
(['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0], ['ax', 'r', [], 0])
它实际上是对同一列表的6个引用的元组。因此,当您遍历它们时,每次都会更改相同的列表。如果您在每次更改时print(path)
而不是axis_slice[0]
,您将清楚地看到发生了什么 - path
的所有6名成员每次都会更改。这是列表可变性的一个特性,并在具有可变成员的列表中使用itertools.product
。
Python和SO退伍军人Ned Batchelder here非常清楚这种效果。特别是 - 看看名为" Mutable aliasing"以下 - 虽然整篇文章真的值得一读。
如何解决此问题将高度依赖于此代码的上下文。