【问题标题】:Split a list into all pairs in all possible ways以所有可能的方式将列表拆分为所有对
【发布时间】:2017-08-16 12:30:11
【问题描述】:

我知道很多帖子都有类似的问题,并且都看过。但是,我无法做我需要做的事情。

我有一个列表说l1=[0,1,2,3,4],我想将它分成如下的一对元组:

 [(0, 1), (2, 3), 4],
 [(0, 1), (2, 4), 3],
 [(0, 1), (3, 4), 2],
 [(0, 2), (1, 3), 4],
 [(0, 2), (1, 4), 5],
 [(0, 2), (3, 4), 1],
 [(0, 3), (1, 2), 4],
 [(0, 3), (2, 4), 1],
 [(0, 3), (1, 4), 2],
 [(0, 4), (1, 2), 3],
 [(0, 4), (1, 3), 2],
 [(0, 4), (2, 3), 1]

我尝试了how-to-split-a-list-into-pairs-in-all-possible-ways帖子中的解决方案。

def all_pairs(lst):
    if len(lst) < 2:
        yield lst
        return
    a = lst[0]
    for i in range(1,len(lst)):
        pair = (a,lst[i])
        for rest in all_pairs(lst[1:i]+lst[i+1:]):
            yield [pair] + rest

我得到以下输出:

[(0, 1), (2, 3), 4]
[(0, 1), (2, 4), 3]
[(0, 2), (1, 3), 4]
[(0, 2), (1, 4), 3]
[(0, 3), (1, 2), 4]
[(0, 3), (1, 4), 2]
[(0, 4), (1, 2), 3]
[(0, 4), (1, 3), 2]

我发现我想要的列表中缺少一些组合。

如果有任何建议,我将不胜感激?

【问题讨论】:

  • 请问这种小众编程问题的用例是什么?
  • 您的第一个列表完整符合您的期望吗?对中的顺序是否无关紧要,对的顺序也是如此吗?目前,这两个答案都产生了更长的答案。
  • 其实为什么0从不出现在最后?您是否还应该拥有[(1, 2), (3, 4), 0][(1, 3), (2, 4), 0] 等?
  • 是的,@NickT 是对的。我还应该有他提到的其他组合。
  • 你的输入总是有 5 个值吗?如果您希望采用可变长度,有时是奇数,有时是偶数,如果您允许奇数显示为 (4, None)(4,) 而不是裸露的 4,可能会更容易。

标签: python list partitioning


【解决方案1】:

您可以使用itertools.permutations 并使用frozenset 过滤掉重复项:

In [173]: d = {frozenset([frozenset(x[:2]), frozenset(x[2:4]), x[-1]]) for x in itertools.permutations(l1, 
     ...: len(l1))}

In [174]: d2 = [sorted(x,  key=lambda x: (not isinstance(x, frozenset), x)) for x in d]

In [175]: sorted([[tuple(x[0]), tuple(x[1]), x[-1]] for x in d2])
Out[175]: 
[[(0, 4), (2, 3), 1],
 [(1, 2), (0, 3), 4],
 [(1, 2), (0, 4), 3],
 [(1, 2), (3, 4), 0],
 [(1, 3), (0, 2), 4],
 [(1, 3), (0, 4), 2],
 [(1, 3), (2, 4), 0],
 [(1, 4), (0, 2), 3],
 [(1, 4), (0, 3), 2],
 [(2, 3), (0, 1), 4],
 [(2, 3), (1, 4), 0],
 [(2, 4), (0, 1), 3],
 [(2, 4), (0, 3), 1],
 [(3, 4), (0, 1), 2],
 [(3, 4), (0, 2), 1]]

【讨论】:

  • 根据他的预期列表看起来他想忽略顺序,所以[(0, 1), (2, 3), 4] == [(0, 1), (3, 2), 4] == [(2, 3), (0, 1), 4]
  • @NickT 基于 OP 想要的输出,是不是很详尽?我会从 OP 那里得到一些澄清。
  • 如果忽略配对内部和配对之间的顺序,他的列表中会缺少什么?
  • @cᴏʟᴅsᴘᴇᴇᴅ [(0, 1), (2, 3), 4][(0, 1), (3, 2), 4] 的副本。实际上,在元组内排序是无关紧要的。如何摆脱这些重复项?
  • @NickT 我使用了一个frozenset并摆脱了那些重复。
【解决方案2】:

您可以使用itertools.permutations,然后使用列表推导从每个排列的前 4 个项目中创建对:

l1=[0,1,2,3,4]
from itertools import permutations
l2 = permutations(l1)
l3 = [[(x[0], x[1]), (x[2], x[3]), x[4]] for x in l2]

【讨论】:

    【解决方案3】:
    [[(0, i), tuple(item for item in l if item not in {0, i ,j}), j] for i in range(1, 5) for j in [item for item in l if item not in {0, i}]]
    
    [[(0, 1), (3, 4), 2],
     [(0, 1), (2, 4), 3],
     [(0, 1), (2, 3), 4],
     [(0, 2), (3, 4), 1],
     [(0, 2), (1, 4), 3],
     [(0, 2), (1, 3), 4],
     [(0, 3), (2, 4), 1],
     [(0, 3), (1, 4), 2],
     [(0, 3), (1, 2), 4],
     [(0, 4), (2, 3), 1],
     [(0, 4), (1, 3), 2],
     [(0, 4), (1, 2), 3]]
    

    【讨论】:

      猜你喜欢
      • 2015-06-21
      • 1970-01-01
      • 2018-11-04
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多