使用itertools.product枚举索引的元组

时间:2019-06-03 15:54:03

标签: python iterator

我正在同时遍历多个列表,并希望生成器同时生成元素及其索引。如果我有两个列表,则将使用嵌套的for循环:

for i_idx, i_val in list_0:
    for j_idx, j_val in list_1:
        print(i_idx, i_val, j_idx, j_val)

但是,由于我有两个以上的列表,因此嵌套解决方案很快变得难以辨认。我通常会使用itertools.product整齐地获取列表的笛卡尔积,但是这种策略不允许我获取每个列表中元素的单独索引。

这是我到目前为止尝试过的:

>>> from itertools import product

>>> list_0 = [1,2]
>>> list_1 = [3,4]
>>> list_2 = [5,6]

>>> for idx, pair in enumerate(product(list_0, list_1, list_2)):
...    print(idx, pair)
0 (1, 3, 5)
1 (1, 3, 6)
2 (1, 4, 5)
3 (1, 4, 6)
4 (2, 3, 5)
5 (2, 3, 6)
6 (2, 4, 5)
7 (2, 4, 6)

我想要的输出是这样:

0 0 0 (1, 3, 5)
0 0 1 (1, 3, 6)
0 1 0 (1, 4, 5)
0 1 1 (1, 4, 6)
1 0 0 (2, 3, 5)
1 0 1 (2, 3, 6)
1 1 0 (2, 4, 5)
1 1 1 (2, 4, 6)

其中,第一,第二和第三列是相应列表中元素的索引。有大量的列表时,有没有清晰的方法可以做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以在功能中再次使用combo和产品:

teams

例如:

import itertools
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
combo = list(itertools.combinations(teams, 2))
def group(c = [], s = []):
   _c = {i for b in c for i in b}
   if all(i in _c for i in teams):
     yield c
     _s = [i for i in combo if i not in s]
     if _s:
       yield from group(c=[_s[0]], s=s+[_s[0]])
   else:
     _c = {i for b in c for i in b}
     _s = [i for i in combo if i not in s and all(j not in _c for j in i)]
     for i in _s:
       yield from group(c=c+[i], s = s+[i])


results, combos = [], group()
_start = next(combos)
while all(all(j not in i for i in results) for j in _start):
   results.append(_start)
   _start = next(combos)

对于[[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)], [(1, 3), (2, 4), (5, 7), (6, 9), (8, 10)], [(1, 4), (2, 3), (5, 8), (6, 10), (7, 9)], [(1, 5), (2, 6), (3, 7), (4, 10), (8, 9)], [(1, 6), (2, 5), (3, 8), (4, 9), (7, 10)], [(1, 7), (2, 8), (3, 9), (4, 6), (5, 10)], [(1, 8), (2, 9), (3, 10), (4, 5), (6, 7)], [(1, 9), (2, 10), (3, 5), (4, 7), (6, 8)], [(1, 10), (2, 7), (3, 6), (4, 8), (5, 9)]]

zip