创建多个列表,其中每个列表都以唯一对的形式包含原始列表中的所有项目

问题描述 投票:0回答:1

我试图将列表中的两个项目以尽可能多的组合随机配对在一起,然后将它们分成多个列表,其中每个项目/组合在所有组合列表中仅包含一次。

例如,如果以下项目在原始列表中: 香蕉苹果桃梨

我想生成以下内容作为单独的列表:

banana apple
peach pear

banana peach
apple pear

banana pear
apple peach

我添加了 12 种水果的列表,然后使用 itertools 从列表中找到了每对组合。我创建了几个新的空列表,并创建了一个 for 循环来检查列表中的任一项目是否已被使用,以及是否必须将其分配给新列表:

fruitcombos = list(it.combinations(fruits, 2))

s1 = []
s2 = []
...
s10 = []

for group in fruitcombos:
    if not any(group[0] in x for x in s1) and not any(group[1] in x for x in s1):
            s1.append(group)
    elif not any(group[0] in x for x in s2) and not any(group[1] in x for x in s2):
            s2.append(group)
    elif not any(group[0] in x for x in s3) and not any(group[1] in x for x in s3):
            s3.append(group)
    ...
    
    elif not any(group[0] in x for x in s10) and not any(group[1] in x for x in s10):
            s10.append(group)

我查看了 itertools 模块并尝试了 round_robin、ncycles、sliding_window 等,但无法弄清楚如何以更优雅的方式解决这个问题。它也无法正常工作 - 通过我尝试过的循环,第一个列表 (s1) 具有预期的 12 个项目中的 12 个。然而,其他列表的数量减少,从第四个列表开始,仅包括 12 个项目中的 8 个,因为其他项目对已包含在其他列表中。我该如何避免这种情况?

我将非常感谢任何帮助。

python list combinations pairwise
1个回答
0
投票
In [4]: def partitions(L, k):
   ...:     combos = list(itertools.combinations(L, k))
   ...:     m = len(combos)//2
   ...:     return [c1+c2 for c1,c2 in zip(combos[:m], combos[m:][::-1])]
   ...:

In [5]: partitions('banana apple peach pear'.split(), 2)
Out[5]:
[('banana', 'apple', 'peach', 'pear'),
 ('banana', 'peach', 'apple', 'pear'),
 ('banana', 'pear', 'apple', 'peach')]

或者,替代

In [6]: def partitions(L, k):
   ...:     combos = list(itertools.combinations(L, k))
   ...:     m = len(combos)//2
   ...:     return list(zip(combos[:m], combos[m:][::-1]))
   ...:

In [7]: partitions('banana apple peach pear'.split(), 2)
Out[7]:
[(('banana', 'apple'), ('peach', 'pear')),
 (('banana', 'peach'), ('apple', 'pear')),
 (('banana', 'pear'), ('apple', 'peach'))]
© www.soinside.com 2019 - 2024. All rights reserved.