代码之家  ›  专栏  ›  技术社区  ›  Jonathan Allen

给定列表中项目的组合

  •  2
  • Jonathan Allen  · 技术社区  · 5 年前

    我现在在巨蟒之地。这就是我要做的。我已经研究过ITertools库,但它似乎只做排列。

    我想获取一个输入列表,比如[‘雅虎’、‘维基百科’、‘自由基’]并生成一个项目与零个或多个其他项目的每个唯一组合…

    ['yahoo', 'wikipedia', 'freebase']
    ['yahoo', 'wikipedia']
    ['yahoo', 'freebase']
    ['wikipedia', 'freebase']
    ['yahoo']
    ['freebase']
    ['wikipedia']
    

    几点注意事项。订单并不重要,我正在尝试设计一种方法来获取任何大小的列表。还有,这种组合有名字吗?

    谢谢你的帮助!

    4 回复  |  直到 14 年前
        1
  •  3
  •   SilentGhost    14 年前
    >>> l = ['yahoo', 'wikipedia', 'freebase']
    >>> import itertools
    >>> for i in range(1, len(l) +1):
        print(list(itertools.combinations(l, r=i)))
    
    
    [('yahoo',), ('wikipedia',), ('freebase',)]
    [('yahoo', 'wikipedia'), ('yahoo', 'freebase'), ('wikipedia', 'freebase')]
    [('yahoo', 'wikipedia', 'freebase')]
    

    P.S.为什么是这个wiki?

        2
  •  3
  •   miles82    14 年前

    它被称为动力集。这是来自 itertools docs :

    def powerset(iterable):
        "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
        s = list(iterable)
        return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
    
        3
  •  0
  •   Bart Kiers    14 年前

    你基本上是从1数到2 n - 1 二进制 :

    0 0 1    ['freebase']
    0 1 0    ['wikipedia']
    0 1 1    ['wikipedia', 'freebase']
    1 0 0    ['yahoo']
    1 0 1    ['yahoo', 'freebase']
    1 1 0    ['yahoo', 'wikipedia']
    1 1 1    ['yahoo', 'wikipedia', 'freebase']
    
        4
  •  0
  •   Alvin Row    14 年前

    这就是所谓的动力装置。跟着这个走 algorithm . 下面是一个简单的实现:

    def powerset(seq):
      if len(seq):
        head = powerset(seq[:-1])
        return head + [item + [seq[-1]] for item in head]
      else:
        return [[]]
    
    >>> powerset(['yahoo', 'wikipedia', 'freebase'])
    [[], ['yahoo'], ['wikipedia'], ['yahoo', 'wikipedia'], ['freebase'], ['yahoo', 'freebase'], ['wikipedia', 'freebase'], ['yahoo', 'wikipedia', 'freebase']]
    

    还有一个:

    def powerset(s):
      sets = []
      indicator = lambda x: x & 1
      for element in xrange(2**len(s)):
        n = element
        subset = []
        for x in s:
            if indicator(n):
                subset.append(x)
            n >>= 1
        sets.append(subset)
      return sets