提问人:CornelioQuinto 提问时间:8/18/2023 更新时间:11/24/2023 访问量:94
3 个列表之间的 Python 组合,一个列表依赖于一个列表
Python combinations between 3 lists with one depending on one list
问:
我有两个列表和第三个列表,它依赖于第一个列表。
l1 = [1, 2]
l2 = [3, 4]
l3 = [[11, 111], [22, 222]] # the numbers are calculated for each element of l1
我想要的是创建一个组合,从而产生:
[(1,3,11), (1,3,111), (1,4,11), (1,4,111), (2,3,22), (2,3,222), (2,4,22), (2,4,222)]
你有什么建议吗?
答:
0赞
C. McCracken
8/18/2023
#1
这个怎么样?
tuples = []
for l1_index, a in enumerate(l1):
for b in l2:
for c in l3[l1_index]:
tuples.append((a,b,c))
print(tuples)
>>> [(1, 3, 11), (1, 3, 111), (1, 4, 11), (1, 4, 111), (2, 3, 22), (2, 3, 222), (2, 4, 22), (2, 4, 222)]
评论
0赞
Kelly Bundy
8/18/2023
尝试for a, cs in zip(l1, l3):
0赞
Alain T.
8/18/2023
#2
l1 和 l3 之间的关系尚不清楚,但假设它只是位置关系,您可以使用带有 zip() 的嵌套推导式来组合 l1 和 l3:
[ (a,b,c) for a,ac in zip(l1,l3) for b in l2 for c in ac ]
[(1, 3, 11), (1, 3, 111), (1, 4, 11), (1, 4, 111), (2, 3, 22),
(2, 3, 222), (2, 4, 22), (2, 4, 222)]
-1赞
Ben A.
8/18/2023
#3
这是我的尝试:
def combine_lists(l1, l2, l3):
result = []
for index, i in enumerate(l1):
for j in l2:
result.append((i, j, l3[index][0]))
result.append((i, j, l3[index][1]))
return result
运行以下命令将生成您描述的结果:
l1 = [1, 2]
l2 = [3, 4]
l3 = [[11, 111], [22, 222]]
combination = combine_lists(l1, l2, l3)
print(combination)
-2赞
CornelioQuinto
8/18/2023
#4
谢谢大家!最后,我得到了这个:
combo = []
for i in range(len(l1)):
for j in range(len(l2)):
for k in range(len(l3[i])):
combo.append((l1[i], l2[j], l3[i][k]))
combo
0赞
bfontaine
8/21/2023
#5
这将起作用:
import itertools
combo = list(itertools.chain(*[
itertools.product([l1[i]], l2, l3[i])
for i in range(len(l1))
]))
这循环了 ,对于每个第 th 个元素,它都会生成与该元素的所有组合,后跟 中第 个列表中的任何一个和任何一个。l1
i
l2
i
l3
合并所有组合列表的调用也可以重写为列表推导式:itertools.chain
combo3 = [
e
for i in range(len(l1))
for e in itertools.product([l1[i]], l2, l3[i])
]
包含长度为 100、 和 1000 次迭代(代码)的所有列表的快速基准测试:len(l3[i]) == 5
- 您的解决方案:4.92s
- 带 : 1.95s
itertools.chain
- 带列表推导:2.13s
评论
0赞
Kelly Bundy
8/21/2023
使用 itertools 似乎很奇怪,但避免 zip...
1赞
Kelly Bundy
8/21/2023
还有另一种方法,通过使用 map 摆脱所有 Python 迭代: 。艺术list(itertools.chain(*map( itertools.product, zip(l1), itertools.repeat(l2), l3 )))
list(itertools.chain.from_iterable(map( itertools.product, zip(l1), itertools.repeat(l2), l3 )))
0赞
bfontaine
8/21/2023
@KellyBundy是获得产品的强制性要求,但不是。itertools
zip
0赞
Kelly Bundy
8/21/2023
但是,使用繁重的导入工具而不使用较小的内置工具,而是使用非 pythonic 索引循环仍然很奇怪。等等,你认为我后来的替代方式是指拉链吗?我没有。我的意思是 l1 和 l3 的并行迭代,正如我在 C. McCracken 的回答中所建议的那样。
0赞
bfontaine
8/21/2023
@KellyBundy 实际上,我发现 McCracken 的答案没有它比有它更容易阅读,但我想使用正确的命名(而不仅仅是 //)它会是一样的。zip
a
b
c
评论