[英]How to 'flatten' generators in python?
I have a problem with 'flattening' out some generators in python. 我在python中“拉平”一些生成器时遇到问题。 Here is my code:
这是我的代码:
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))
which gives me: 这给了我:
[(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))]
However, I want something like: 但是,我想要类似的东西:
[(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)]
In general the function should give me generators for all possible paths to go through a list, ie from test[0] -> test[1] -> ... -> test[n]
where n
is len(test)
. 通常,该函数应为我生成所有可能通过列表的路径生成器,即
from test[0] -> test[1] -> ... -> test[n]
,其中n
为len(test)
。 Here, it picks up at each step one element. 在这里,它在每个步骤中拾取一个元素。
Similar to what the following function returns, just with generators: 类似于以下函数返回的内容,仅包含生成器:
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)
I played around with it.chain
and it.chain.from_iterable
but can't seem to make it work. 我玩过
it.chain
和it.chain.from_iterable
但似乎无法正常工作。 The problem is that my 'test' list are variable in size and length and thus I have to do the whole thing recursively. 问题是我的“测试”列表的大小和长度是可变的,因此我必须递归地进行整个操作。
Edit: 编辑:
itertools.product(*test)
works as pointed out by John Coleman 约翰·科尔曼(John Coleman)指出的作品
Here's one way to calculate a product
of lists without using the built-in 这是一种无需使用内置函数即可计算列表
product
的方法
def product (*iters):
def loop (prod, first = [], *rest):
if not rest:
for x in first:
yield prod + (x,)
else:
for x in first:
yield from loop (prod + (x,), *rest)
yield from loop ((), *iters)
for prod in product ("ab", "xyz"):
print (prod)
# ('a', 'x')
# ('a', 'y')
# ('a', 'z')
# ('b', 'x')
# ('b', 'y')
# ('b', 'z')
In python, we can collect the outputs of a generator in a list by using the list
constructor. 在python中,我们可以使用
list
构造函数将生成器的输出收集在list
。 Note we can also calculate the product of more than two inputs as seen below 请注意,我们还可以计算两个以上输入的乘积,如下所示
print (list (product ("+-", "ab", "xyz")))
# [ ('+', 'a', 'x')
# , ('+', 'a', 'y')
# , ('+', 'a', 'z')
# , ('+', 'b', 'x')
# , ('+', 'b', 'y')
# , ('+', 'b', 'z')
# , ('-', 'a', 'x')
# , ('-', 'a', 'y')
# , ('-', 'a', 'z')
# , ('-', 'b', 'x')
# , ('-', 'b', 'y')
# , ('-', 'b', 'z')
# ]
Because product
accepts aa list of iterables , any iterable input can be used in the product. 因为
product
接受可迭代列表,所以任何可迭代输入都可以在产品中使用。 They can even be mixed as demonstrated below 它们甚至可以混合在一起,如下所示
print (list (product (['@', '%'], range (2), "xy")))
# [ ('@', 0, 'x')
# , ('@', 0, 'y')
# , ('@', 1, 'x')
# , ('@', 1, 'y')
# , ('%', 0, 'x')
# , ('%', 0, 'y')
# , ('%', 1, 'x')
# , ('%', 1, 'y')
# ]
Because product
is defined as a generator, we are afforded much flexibility even when writing more complex programs. 因为
product
被定义为生成器,所以即使编写更复杂的程序,我们也能获得很大的灵活性。 Consider this program that finds right triangles made up whole numbers, a Pythagorean triple . 考虑一下该程序,该程序查找由整数组成的直角三角形,即勾股三元组 。 Also note that
product
allows you to repeat an iterable as input as see in product (r, r, r)
below 还要注意,
product
允许您重复进行迭代作为输入,如下面product (r, r, r)
所示
def is_triple (prod):
(a,b,c) = prod
return a * a + b * b == c * c
def solver (n):
r = range (1,n)
for p in product (r, r, r):
if is_triple (p):
yield p
print (list (solution in solver (20)))
# (3, 4, 5)
# (4, 3, 5)
# (5, 12, 13)
# (6, 8, 10)
# (8, 6, 10)
# (8, 15, 17)
# (9, 12, 15)
# (12, 5, 13)
# (12, 9, 15)
# (15, 8, 17)
For additional explanation and a way to see how to do this without using generators, view this answer . 有关其他说明以及查看如何不使用生成器的方法,请查看此答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.