【发布时间】:2019-06-15 06:00:45
【问题描述】:
我在 python 中“扁平化”一些生成器时遇到问题。这是我的代码:
import itertools as it
test = [[1,2,3],[4,5],[6,7,8]]
def comb(possible):
if len(possible) != 1:
for a in possible[0]:
yield from it.product((a,), comb(possible[1:]))
else:
yield from possible[0]
list(comb(test))
这给了我:
[(1, (4, 6)),
(1, (4, 7)),
(1, (4, 8)),
(1, (5, 6)),
(1, (5, 7)),
(1, (5, 8)),
(2, (4, 6)),
(2, (4, 7)),
(2, (4, 8)),
(2, (5, 6)),
(2, (5, 7)),
(2, (5, 8)),
(3, (4, 6)),
(3, (4, 7)),
(3, (4, 8)),
(3, (5, 6)),
(3, (5, 7)),
(3, (5, 8))]
但是,我想要类似的东西:
[(1, 4, 6),
(1, 4, 7),
(1, 4, 8),
(1, 5, 6),
(1, 5, 7),
(1, 5, 8),
(2, 4, 6),
(2, 4, 7),
(2, 4, 8),
(2, 5, 6),
(2, 5, 7),
(2, 5, 8),
(3, 4, 6),
(3, 4, 7),
(3, 4, 8),
(3, 5, 6),
(3, 5, 7),
(3, 5, 8)]
一般来说,该函数应该为我提供所有可能路径的生成器以通过列表,即from test[0] -> test[1] -> ... -> test[n],其中n 是len(test)。在这里,它在每一步都选取一个元素。
类似于以下函数的返回,只是使用生成器:
def prod(possible):
if len(possible) != 1:
b = []
for i in range(len(possible[0])):
for x in prod(possible[1:]):
if len(possible) == 2:
b += [[possible[0][i]]+[x]]
else:
b += [[possible[0][i]]+x]
return b
else:
return possible[0]
prod(test)
我玩过it.chain 和it.chain.from_iterable,但似乎无法正常工作。问题是我的“测试”列表的大小和长度是可变的,因此我必须递归地完成整个事情。
编辑:
itertools.product(*test)
正如约翰·科尔曼指出的那样工作
【问题讨论】:
-
根据您的函数名称,您是否正在寻找
itertools.combinations?无论哪种方式,仅从代码和输出示例都很难判断该函数应该做什么。 -
itertools.product(*test)? -
你用的是什么版本的python?
-
正如 John Coleman 所指出的,您似乎想要
itertools.product。他的单线提供了一个生成器,可以产生你想要的。 -
itertools.product(*test) 完成了这项工作。我不知道我可以提出这样的论点。非常感谢。
标签: python recursion iterator itertools yield