Python:将不同长度的多个列表的子产品合并到一个元组列表中

Python:将不同长度的多个列表的子产品合并到一个元组列表中,python,list,itertools,Python,List,Itertools,我尝试使用以下方法将不同长度的多个列表的子产品合并到元组列表中: import itertools letters = ['a', 'b', 'c'] symbols = ['*', '#', '+'] numbers = [1, 2, 3, 4, 5] tuples_of_two = zip(letters, symbols) tuples_of_three = list(itertools.product(tuples_of_two, numbers)) print(tuples_of

我尝试使用以下方法将不同长度的多个列表的子产品合并到元组列表中:

import itertools

letters = ['a', 'b', 'c']
symbols = ['*', '#', '+']
numbers = [1, 2, 3, 4, 5]

tuples_of_two = zip(letters, symbols)
tuples_of_three = list(itertools.product(tuples_of_two, numbers))

print(tuples_of_three)
这将生成包含元组和数字的元组列表:

[(('a', '*'), 1),
 (('a', '*'), 2),
 (('a', '*'), 3),
 (('a', '*'), 4),
 (('a', '*'), 5),
 (('b', '#'), 1),
 (('b', '#'), 2),
 (('b', '#'), 3),
 (('b', '#'), 4),
 (('b', '#'), 5),
 (('c', '+'), 1),
 (('c', '+'), 2),
 (('c', '+'), 3),
 (('c', '+'), 4),
 (('c', '+'), 5)]
但实际上我试图得到以下结果,即没有“子元组”的元组列表:

并不是说在元组中,我只希望“a”与“*”结合,“b”与“#”结合,“c”与“+”结合,所以它不是intertools.product可以达到的完整乘积

这可能是通过使用某种列表共同理解来实现的,这种理解将元组的第一个元素“解耦”,或者直接使用更优雅的方式

但是我现在被困住了

有人能帮忙吗


提前谢谢

itertools.product
执行与嵌套for循环相同的操作。您可以使用
zip
的直接列表理解功能,一次性完成所需内容:

[(l, s, n) for l, s in zip(letters, symbols) for n in numbers]

#[('a', '*', 1),
# ('a', '*', 2),
# ('a', '*', 3),
# ('a', '*', 4),
# ('a', '*', 5),
# ('b', '#', 1),
# ...

itertools.product
执行与嵌套for循环相同的操作。您可以使用
zip
的直接列表理解功能,一次性完成所需内容:

[(l, s, n) for l, s in zip(letters, symbols) for n in numbers]

#[('a', '*', 1),
# ('a', '*', 2),
# ('a', '*', 3),
# ('a', '*', 4),
# ('a', '*', 5),
# ('b', '#', 1),
# ...

通过构建一个新元组,将内部元组添加到单个元组,可以将元组展平:

tuples_of_three =  [x+(y,) for x, y in itertools.product(tuples_of_two, numbers)]

通过构建一个新元组,将内部元组添加到单个元组,可以将元组展平:

tuples_of_three =  [x+(y,) for x, y in itertools.product(tuples_of_two, numbers)]
它应该适合您:

('a', '*', 1)
('a', '*', 2)
('a', '*', 3)
('a', '*', 4)
('a', '*', 5)
('a', '#', 1)
('a', '#', 2)
('a', '#', 3)
('a', '#', 4)
('a', '#', 5)
('a', '+', 1)
('a', '+', 2)
('a', '+', 3)
('a', '+', 4)
('a', '+', 5)
('b', '*', 1)
('b', '*', 2)
('b', '*', 3)
('b', '*', 4)
('b', '*', 5)
('b', '#', 1)
('b', '#', 2)
...
它应该适合您:

('a', '*', 1)
('a', '*', 2)
('a', '*', 3)
('a', '*', 4)
('a', '*', 5)
('a', '#', 1)
('a', '#', 2)
('a', '#', 3)
('a', '#', 4)
('a', '#', 5)
('a', '+', 1)
('a', '+', 2)
('a', '+', 3)
('a', '+', 4)
('a', '+', 5)
('b', '*', 1)
('b', '*', 2)
('b', '*', 3)
('b', '*', 4)
('b', '*', 5)
('b', '#', 1)
('b', '#', 2)
...

摘自
itertools.product()
文档:

产品(A,B)返回的值与:((x,y)表示A中的x表示B中的y)

因此,您可以这样做:

letters = ['a', 'b', 'c']
symbols = ['*', '#', '+']
numbers = [1, 2, 3, 4, 5]

print([(letter, symbol, number) for letter, symbol in zip(letters, symbols) for number in numbers])

摘自
itertools.product()
文档:

产品(A,B)返回的值与:((x,y)表示A中的x表示B中的y)

因此,您可以这样做:

letters = ['a', 'b', 'c']
symbols = ['*', '#', '+']
numbers = [1, 2, 3, 4, 5]

print([(letter, symbol, number) for letter, symbol in zip(letters, symbols) for number in numbers])
有点“通用”的解决方案,使用
zip(numbers)
将数字包装成元组。然后,您统一地只有元组,它们可以简单地求和

>>> if 1:
    import itertools, pprint

    letters = ['a', 'b', 'c']
    symbols = ['*', '#', '+']
    numbers = [1, 2, 3, 4, 5]
    zips = zip(letters, symbols), zip(numbers)

    result = [sum(p, ()) for p in itertools.product(*zips)]

    pprint.pprint(result)


[('a', '*', 1),
 ('a', '*', 2),
 ('a', '*', 3),
 ('a', '*', 4),
 ('a', '*', 5),
 ('b', '#', 1),
 ('b', '#', 2),
 ('b', '#', 3),
 ('b', '#', 4),
 ('b', '#', 5),
 ('c', '+', 1),
 ('c', '+', 2),
 ('c', '+', 3),
 ('c', '+', 4),
 ('c', '+', 5)]
>>> 
这也适用于更复杂的组合,您只需定义它们,例如:

    zips = zip(letters, symbols), zip(numbers), zip(symbols, letters, numbers)
如果有更多/更长的元组,那么将它们链接起来可能会更有效:

    result = [tuple(itertools.chain.from_iterable(p))
              for p in itertools.product(*zips)]
有点“通用”的解决方案,使用
zip(numbers)
将数字包装成元组。然后,您统一地只有元组,它们可以简单地求和

>>> if 1:
    import itertools, pprint

    letters = ['a', 'b', 'c']
    symbols = ['*', '#', '+']
    numbers = [1, 2, 3, 4, 5]
    zips = zip(letters, symbols), zip(numbers)

    result = [sum(p, ()) for p in itertools.product(*zips)]

    pprint.pprint(result)


[('a', '*', 1),
 ('a', '*', 2),
 ('a', '*', 3),
 ('a', '*', 4),
 ('a', '*', 5),
 ('b', '#', 1),
 ('b', '#', 2),
 ('b', '#', 3),
 ('b', '#', 4),
 ('b', '#', 5),
 ('c', '+', 1),
 ('c', '+', 2),
 ('c', '+', 3),
 ('c', '+', 4),
 ('c', '+', 5)]
>>> 
这也适用于更复杂的组合,您只需定义它们,例如:

    zips = zip(letters, symbols), zip(numbers), zip(symbols, letters, numbers)
如果有更多/更长的元组,那么将它们链接起来可能会更有效:

    result = [tuple(itertools.chain.from_iterable(p))
              for p in itertools.product(*zips)]

[(字母[i],符号[i],n)表示itertools.product中的i,n(范围(len(字母)),数字)]
flatte\u tuple=lambda(嵌套,外部标量):嵌套+(外部标量),
,以防万一。“我不相信这是你真正想要的。你真的想要一个只与*?而不是与#或+?”我不希望它像我解释的那样带有#或+@史蒂芬·波克曼:你现在是不是因为我的反应不够快而投了反对票?谢谢你的回答!这救了我一天。@Stefan Pochmann:你能再次投票吗!?我想这个问题很有价值,因为我还没有在这上面找到任何东西。
[(字母[I],符号[I],n)在itertools.product(范围(len(字母)),数字)]
flatte\u tuple=lambda(嵌套,外部标量):嵌套+(外部标量,)
,以防万一。“我不相信这是你真正想要的。你真的想要一个只有*的组合吗?不使用#或+?“我不希望它像解释的那样带有#或+@史蒂芬·波克曼:你现在是不是因为我的反应不够快而投了反对票?谢谢你的回答!这救了我一天。@Stefan Pochmann:你能再次投票吗!?我想问题是有价值的,因为我没有在上面找到任何东西。我想这是OP真正想要的,@stefanpochman注释是现场的,他真的想要
a
只与
*
结合,而不是与
、+结合使用
+
?不需要ා和+所以答案不完全是我想要的。无论如何谢谢你!我猜这就是OP真正想要的,@StefanPochmann评论说,他真的想要一个只与
*
结合的
,而不是与
+
?不是与#和+结合的
吗?所以答案并不完全是我想要的。无论如何谢谢你!谢谢你的回答。我选择Psidom的答案,因为我甚至不需要intertools。但是你的也很好用!谢谢你的回答。我选择Psidom的答案,因为我甚至不需要intertools。但是你的也很好用!这是一个很好的解决方案,与Psidoms完全相同!这是一个很好的解决方案,与Psidoms完全相同!你的回答基本上把我的代码减少了大约60%。再次感谢!你的回答基本上把我的代码减少了大约60%。再次感谢!