Python 生成器的起源

标签 python generator

我正在尝试制定一种通用方法来生成多个范围或列表的所有组合,例如,

[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输出元组列表

输入:

import itertools

a= [range(0, 2), range(2, 5), range(4, 6), range(2, 3)]
list(itertools.product(*a))

输出:

[(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 =  list( a + [b] for a in x[-1] for b in rgs[3]) 

大多数不了解 itertools 的人都会这样做:

x=[]
for i0 in rgs[0]:
    for i1 in rgs[1]:
        for i2 in rgs[2]:
            for i3 in rgs[3]:
                x.append([i0,i1,i2,i3])

或者使用列表理解(不要这样做,它看起来非常困惑):

[[i0,i1,i2,i3] for i3 in rgs[3] for i2 in rgs[2] for i1 in rgs[1] for i0 in rgs[0]]

关于Python 生成器的起源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52546783/

相关文章:

python - 从 matplotlib 导入地理图到 plotly

python - 从 Python 创建 JSON 的更有效方法

ruby-on-rails - 禁用生成请求和路由规范? [RSPEC]

javascript - 将函数 * 提升为异步函数 *?

android - 素材图片android

dsl - 以自定义语言实现“生成器”支持

javascript - 为什么在此示例中使用生成器函数比填充和迭代数组慢?

python - 在ubuntu中安装jpeg模块

python - 如何为大型(200,000 多条记录)集合运行 pymongo 聚合查询?

python - Google Cloud OAuth 同意屏幕未反射(reflect)(内部)应用程序范围的更改