【问题标题】:Python itertools combinations customizingPython itertools 组合定制
【发布时间】:2018-04-08 18:36:41
【问题描述】:

我正在做一个基于组合的问题,只是卡在里面。是的,我的 python 不太好。

使用 ncr 的 itertools 组合函数只返回 n 中的 r 个可能的组合。我想要一些东西,它会返回选择的 r 个可能的组合,以及 n 个数字中未在该迭代中选择的其他剩余元素。

例子:

>>>from itertools import combinations
>>>list = [1, 2, 3, 4, 5]
>>>rslt = combinations(list, 2)

when [2, 4] is selected it should also return [1, 3, 5] 所以它应该像[[2, 4], [1, 3, 5]]一样返回

提前致谢

【问题讨论】:

    标签: python combinations itertools


    【解决方案1】:

    itertools.combinations

    从输入迭代中返回 r 个长度的元素子序列。

    您可以使用列表推导来获取其他项目[j for j in l if j not in i]

    from itertools import combinations
    
    l = [1, 2, 3, 4, 5]
    
    for i in combinations(l,2):
        print(list(i),[j for j in l if j not in i])
    

    你会得到:

    [1, 2] [3, 4, 5]
    [1, 3] [2, 4, 5]
    [1, 4] [2, 3, 5]
    [1, 5] [2, 3, 4]
    [2, 3] [1, 4, 5]
    [2, 4] [1, 3, 5]
    [2, 5] [1, 3, 4]
    [3, 4] [1, 2, 5]
    [3, 5] [1, 2, 4]
    [4, 5] [1, 2, 3]
    

    顺便说一句,不建议使用list作为变量名。

    【讨论】:

    • 这可以在一行列表理解中完成吗?
    • @Arman [(list(i),[j for j in l if j not in i]) for i in combinations(l,2)]
    • 谢谢,记住不要用它作为变量名
    【解决方案2】:

    最简单的方法是复制原始列表,删除组合中的元素:

    from itertools import combinations
    def combinations_and_remaining(l, n):
        for c in combinations(l, n):
            diff = [i for i in l if i not in c]
            yield c, diff 
    
    for i in combinations_and_remaining([1, 2, 3, 4, 5], 2):
        print(i)
    

    会输出

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

    (组合返回元组;剩余元素作为列表返回以提高效率)

    【讨论】:

      【解决方案3】:

      一种稍微奢侈但有趣的方法是使用combinations 两次:

      from itertools import combinations
      n = 5
      k = 2
      lst = list(range(1, n+1))
      rslt = zip(combinations(lst, k), map(tuple, reversed(list(combinations(lst, n-k)))))
      print(list(rslt))
      # -> [((1, 2), (3, 4, 5)), ((1, 3), (2, 4, 5)), ((1, 4), (2, 3, 5)),
      #     ((1, 5), (2, 3, 4)), ((2, 3), (1, 4, 5)), ((2, 4), (1, 3, 5)),
      #     ((2, 5), (1, 3, 4)), ((3, 4), (1, 2, 5)), ((3, 5), (1, 2, 4)),
      #     ((4, 5), (1, 2, 3))]
      

      【讨论】:

        【解决方案4】:

        您可以通过使用集合来避免循环并提高可读性,例如:

        from itertools import combinations
        
        input = [1,2,3,4,5]
        
        for n in itertools.combinations(input, 2):
            print(n , set(n) ^ set(input))
        

        也就是说,当然,假设原始文件中没有重复项,在转换为集合时会丢失。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-07
          • 1970-01-01
          相关资源
          最近更新 更多