【问题标题】:Find all combinations of pairings between two lists x and y, such that all elements from y are paired with exactly one from x找到两个列表 x 和 y 之间的所有配对组合,使得 y 中的所有元素都与 x 中的一个元素配对
【发布时间】:2020-02-10 08:18:16
【问题描述】:

我试图在 python3 中找到两个列表 x 和 y 中元素的每个唯一组合,这样对于每个组合,列表 y 中的所有元素都与列表 x 中的一个元素配对(min(x,y) ^ @987654323 @组合)。例如,使用以下内容:

x = ['a', 'b', 'c']
y = [1, 2, 3]

combos = get_combos(x,y)
for combo in combos:
    print(combo)

...我想写get_combos(x, y),这样它会返回一个包含 27 对组合的列表,打印时看起来像:

[('a', 1) ('a', 2) ('a', 3)]
[('a', 1) ('a', 2) ('b', 3)]
[('a', 1) ('a', 2) ('c', 3)]
[('a', 1) ('b', 2) ('a', 3)]
[('a', 1) ('b', 2) ('b', 3)]
[('a', 1) ('b', 2) ('c', 3)]
[('a', 1) ('c', 2) ('a', 3)]
[('a', 1) ('c', 2) ('b', 3)]
[('a', 1) ('c', 2) ('c', 3)]
[('b', 1) ('a', 2) ('a', 3)]
[('b', 1) ('a', 2) ('b', 3)]
[('b', 1) ('a', 2) ('c', 3)]
[('b', 1) ('b', 2) ('a', 3)]
[('b', 1) ('b', 2) ('b', 3)]
[('b', 1) ('b', 2) ('c', 3)]
[('b', 1) ('c', 2) ('a', 3)]
[('b', 1) ('c', 2) ('b', 3)]
[('b', 1) ('c', 2) ('c', 3)]
[('c', 1) ('a', 2) ('a', 3)]
[('c', 1) ('a', 2) ('b', 3)]
[('c', 1) ('a', 2) ('c', 3)]
[('c', 1) ('b', 2) ('a', 3)]
[('c', 1) ('b', 2) ('b', 3)]
[('c', 1) ('b', 2) ('c', 3)]
[('c', 1) ('c', 2) ('a', 3)]
[('c', 1) ('c', 2) ('b', 3)]
[('c', 1) ('c', 2) ('c', 3)]

我查看了 itertools.combinations、itertools.product 和 itertools.permutations,但它们似乎都没有提供我正在寻找的东西。当与zip 一起使用时,itertools.permutations 让我很接近(请参阅this answer),但结果列表是排他性的,因为任一列表中的任何元素都不能在单个组合中重复(例如,[('a', 1), ('a', 2), ('c', 3)] 将被留下out),这不是我想要的。 itertools 会为此工作还是需要从头开始编写?

【问题讨论】:

    标签: python list combinations


    【解决方案1】:

    对我来说,这看起来像是 itertools.productzip 的任务,我会这样做:

    import itertools
    x = ['a', 'b', 'c']
    y = [1, 2, 3]
    for t in itertools.product(x,repeat=3):
        print(list(zip(t,y)))
    

    输出:

    [('a', 1), ('a', 2), ('a', 3)]
    [('a', 1), ('a', 2), ('b', 3)]
    [('a', 1), ('a', 2), ('c', 3)]
    [('a', 1), ('b', 2), ('a', 3)]
    [('a', 1), ('b', 2), ('b', 3)]
    [('a', 1), ('b', 2), ('c', 3)]
    [('a', 1), ('c', 2), ('a', 3)]
    [('a', 1), ('c', 2), ('b', 3)]
    [('a', 1), ('c', 2), ('c', 3)]
    [('b', 1), ('a', 2), ('a', 3)]
    [('b', 1), ('a', 2), ('b', 3)]
    [('b', 1), ('a', 2), ('c', 3)]
    [('b', 1), ('b', 2), ('a', 3)]
    [('b', 1), ('b', 2), ('b', 3)]
    [('b', 1), ('b', 2), ('c', 3)]
    [('b', 1), ('c', 2), ('a', 3)]
    [('b', 1), ('c', 2), ('b', 3)]
    [('b', 1), ('c', 2), ('c', 3)]
    [('c', 1), ('a', 2), ('a', 3)]
    [('c', 1), ('a', 2), ('b', 3)]
    [('c', 1), ('a', 2), ('c', 3)]
    [('c', 1), ('b', 2), ('a', 3)]
    [('c', 1), ('b', 2), ('b', 3)]
    [('c', 1), ('b', 2), ('c', 3)]
    [('c', 1), ('c', 2), ('a', 3)]
    [('c', 1), ('c', 2), ('b', 3)]
    [('c', 1), ('c', 2), ('c', 3)]
    

    注意itertools.product 类似于里程表的性质

    【讨论】:

      【解决方案2】:

      没有导入的基本递归解决方案:

      x = ['a', 'b', 'c']
      y = [1, 2, 3]
      def groups(d, c=[]):
        if len(c) == len(x):
          yield list(zip(c, y))
        else:
          for i in d:
             yield from groups(d, c+[i])
      
      print(list(groups(x)))
      

      输出:

      [[('a', 1), ('a', 2), ('a', 3)], [('a', 1), ('a', 2), ('b', 3)], [('a', 1), ('a', 2), ('c', 3)], [('a', 1), ('b', 2), ('a', 3)], [('a', 1), ('b', 2), ('b', 3)], [('a', 1), ('b', 2), ('c', 3)], [('a', 1), ('c', 2), ('a', 3)], [('a', 1), ('c', 2), ('b', 3)], [('a', 1), ('c', 2), ('c', 3)], [('b', 1), ('a', 2), ('a', 3)], [('b', 1), ('a', 2), ('b', 3)], [('b', 1), ('a', 2), ('c', 3)], [('b', 1), ('b', 2), ('a', 3)], [('b', 1), ('b', 2), ('b', 3)], [('b', 1), ('b', 2), ('c', 3)], [('b', 1), ('c', 2), ('a', 3)], [('b', 1), ('c', 2), ('b', 3)], [('b', 1), ('c', 2), ('c', 3)], [('c', 1), ('a', 2), ('a', 3)], [('c', 1), ('a', 2), ('b', 3)], [('c', 1), ('a', 2), ('c', 3)], [('c', 1), ('b', 2), ('a', 3)], [('c', 1), ('b', 2), ('b', 3)], [('c', 1), ('b', 2), ('c', 3)], [('c', 1), ('c', 2), ('a', 3)], [('c', 1), ('c', 2), ('b', 3)], [('c', 1), ('c', 2), ('c', 3)]]
      

      【讨论】:

        【解决方案3】:

        这是产生 27 的 combination_with_replacement 和 permutations 的组合。

        a = set([])
        for i in combinations_with_replacement(['a','b','c'],3):
            for j in permutations(i):
                a.add(j)
        
        assert len(a) == 27
        
        for i in a:
            print(list(zip(i,[1,2,3])))
        

        产量:

        [('b', 1), ('b', 2), ('b', 3)]
        [('a', 1), ('a', 2), ('c', 3)]
        [('b', 1), ('a', 2), ('b', 3)]
        [('c', 1), ('a', 2), ('c', 3)]
        [('c', 1), ('b', 2), ('a', 3)]
        [('c', 1), ('c', 2), ('c', 3)]
        [('a', 1), ('c', 2), ('a', 3)]
        [('c', 1), ('b', 2), ('c', 3)]
        [('c', 1), ('a', 2), ('a', 3)]
        [('a', 1), ('a', 2), ('a', 3)]
        [('a', 1), ('c', 2), ('b', 3)]
        [('a', 1), ('c', 2), ('c', 3)]
        [('c', 1), ('c', 2), ('a', 3)]
        [('c', 1), ('b', 2), ('b', 3)]
        [('a', 1), ('b', 2), ('a', 3)]
        [('c', 1), ('c', 2), ('b', 3)]
        [('a', 1), ('a', 2), ('b', 3)]
        [('b', 1), ('c', 2), ('a', 3)]
        [('b', 1), ('b', 2), ('c', 3)]
        [('c', 1), ('a', 2), ('b', 3)]
        [('b', 1), ('a', 2), ('c', 3)]
        [('b', 1), ('c', 2), ('c', 3)]
        [('b', 1), ('a', 2), ('a', 3)]
        [('a', 1), ('b', 2), ('c', 3)]
        [('a', 1), ('b', 2), ('b', 3)]
        [('b', 1), ('b', 2), ('a', 3)]
        [('b', 1), ('c', 2), ('b', 3)]
        

        【讨论】:

          【解决方案4】:

          试试这个

          import itertools
          L = ['a','b','c']
          P = list( itertools.product(L, repeat=3) )
          [ [(x,1),(y,2),(z,3)] for x,y,z in P ]
          

          【讨论】:

            猜你喜欢
            • 2023-03-19
            • 2021-11-19
            • 1970-01-01
            • 2021-09-16
            • 1970-01-01
            • 2016-08-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多