Python:以代数方式连接列表列表

yo'*_*yo' 4 python list python-itertools

在数学中,当你有两组单词A = {foo,bar}B = {x,y}时,那么代数(或每个到每个)的产品是AB = {foox,fooy,barx,bary}.我想在Python中使用类似的东西.给出两组单词(=列表列表):

A = [ [0,1], [2,3] ]
B = [ [4,5], [6,7] ]
Run Code Online (Sandbox Code Playgroud)

我想将它们连接在一起:

AB = [ [0,1,4,5], [0,1,6,7], [2,3,4,5], [2,3,6,7] ]
Run Code Online (Sandbox Code Playgroud)

这本身并不困难,可以通过以下方式完成product:

AB = [ a+b for (a,b) in itertools.product(A,B) ]
Run Code Online (Sandbox Code Playgroud)

但是,我有一个"集合"列表(又名列表清单)

A = [ [0,1], [2,3] ]
B = [ [4,5], [6,7] ]
C = [ [4,5], [6,7] ]
SETS = [A,B,C]
Run Code Online (Sandbox Code Playgroud)

现在我可以手动完成

ABC = [ a+b+c for (a,b,c) in itertools.product(A,B,C) ]
Run Code Online (Sandbox Code Playgroud)

但如果我有20套连接,我不能这样做.那么,如何编写一个ABC只使用的定义,SETS并接受任何大小的定义?

Nig*_*nel 7

ABC = [ sum(z, []) for z in itertools.product(*SETS) ]
Run Code Online (Sandbox Code Playgroud)

product(*SETS)基本上product(A, B, C).技术术语是参数解包.

sum(z, [])基本上a + b + c + [].

编辑:

聪明人在评论中说,这sum不是加入列表清单的最佳方式.O(n ^ 2)时间复杂度非常残酷.

引用文档:

对于某些用例,sum()有很好的替代方法.连接字符串序列的首选快速方法是调用'.join(sequence).要以扩展精度添加浮点值,请参阅math.fsum().要连接一系列迭代,请考虑使用itertools.chain().

那更好:

from itertools import chain, product
ABC = [ list(chain(*z)) for z in product(*SETS) ]
Run Code Online (Sandbox Code Playgroud)

或者,如果两个参数解包是一个参数解包太多:

ABC = [ list(chain.from_iterable(z)) for z in product(*SETS) ]
Run Code Online (Sandbox Code Playgroud)

或者,如果你进入map:

ABC = map(list, map(chain.from_iterable, product(*SETS)))
Run Code Online (Sandbox Code Playgroud)

  • @delnan是的,那里是`itertools.chain`.我失踪的一步显然是打开包装.我从来没有见过它! (3认同)