我试图用一种通用的方法来生成多个范围或列表的所有组合,例如
[range(0, 2), range(2, 5), range(4, 6), range(2, 3)]
它应该返回一个2x3x2x1=12元素列表。你知道吗
[[0, 2, 4, 2],
[0, 2, 5, 2],
[0, 3, 4, 2],
[0, 3, 5, 2],
[0, 4, 4, 2],
[0, 4, 5, 2],
[1, 2, 4, 2],
[1, 2, 5, 2],
[1, 3, 4, 2],
[1, 3, 5, 2],
[1, 4, 4, 2],
[1, 4, 5, 2]]
到目前为止,这里一切都很好。当我硬编码的时候
x = [ ( [a,b] for a in rgs[0] for b in rgs[1] ) ]
x.append( ( a + [b] for a in x[-1] for b in rgs[2]) )
x.append( ( a + [b] for a in x[-1] for b in rgs[3]) )
我得到了好结果。然而,当我试图概括它时
x = [ ( [a,b] for a in rgs[0] for b in rgs[1] ) ]
for i in range(1,len(rgs)-1):
x.append( ( a + [b] for a in x[-1] for b in rgs[i+1]) )
我得到一个6元素列表:
[[0, 2, 2, 2],
[0, 3, 2, 2],
[0, 4, 2, 2],
[1, 2, 2, 2],
[1, 3, 2, 2],
[1, 4, 2, 2]]
另外,我注意到在前两个之后生成的所有范围都使用rgs[-1]
中的范围,而不是正确的范围。我很难理解为什么会发生这种情况,因为我认为这两个代码示例是相同的,只是后者是任意大量范围的更一般形式。你知道吗
可以使用
itertools.product
输出元组列表输入:
输出:
我在运行第一个代码时没有得到相同的结果。我不得不改变一下:
大多数不了解itertools的人都会这样做:
或者使用列表理解(不要这样做,它看起来非常混乱):
您的问题与在循环中创建生成器表达式有关。生成器表达式被实现为函数,与函数一样,它们可以有“自由”变量,在包含的名称空间中查找这些变量。生成器表达式正在从其定义之外访问
i
,因此,它们最终会看到您期望的不同的i
值。你知道吗下面是一个更容易理解的示例:
在这里,我没有使用
i
值来做一些有用的事情,而是编写了一个生成器函数来打印它。如果运行此代码,您将看到所有生成器都打印出2
,因为这是它们最终运行时(第一个循环结束后)的i
值。你知道吗您的情况稍微微妙一点,因为您在创建下一个生成器时使用上一个生成器,但总体思路是相同的。您期望在
rgs[2]
之上的生成器表达式循环实际上在rgs[3]
之上,因为在声明生成器表达式和使用生成器表达式之间,rgs[i+1]
和i
实际上在查找它。你知道吗相关问题 更多 >
编程相关推荐