Python组合没有重复

时间:2016-04-05 14:38:14

标签: python

我有一个数字列表,我想从中组合。如果我有清单:

HTTP ResolvingName progress 0/
HTTP ConnectingToServer progress 0/
HTTP SendingHeaders progress 0/
HTTP WaitingForResponse progress 0/
HTTP ReceivingHeaders progress 0/
HTTP ReceivingContent progress 0/109192147
done

结果是:

t = [2,2,2,2,4]
c = list(itertools.combinations(t, 4))

但我想得到:

(2, 2, 2, 2)
(2, 2, 2, 4)
(2, 2, 2, 4)
(2, 2, 2, 4)
(2, 2, 2, 4)

除了制作新列表和浏览第一个列表外,是否可以消除重复?

3 个答案:

答案 0 :(得分:7)

我知道这已经晚了但我想补充一点。

对于大多数情况,

set(itertools.combinations(t, 4))会做得很好,但它仍会在内部迭代所有重复组合,因此它可能在计算上很重。如果实际的唯一组合不多,情况尤其如此。

这个只迭代唯一的组合:

from itertools import chain,repeat,islice,count
from collections import Counter

def combinations_without_repetition(r, iterable=None, values=None, counts=None):
  if iterable:
    values, counts = zip(*Counter(iterable).items())

  f = lambda i,c: chain.from_iterable(map(repeat, i, c))
  n = len(counts)
  indices = list(islice(f(count(),counts), r))
  if len(indices) < r:
    return
  while True:
    yield tuple(values[i] for i in indices)
    for i,j in zip(reversed(range(r)), f(reversed(range(n)), reversed(counts))):
      if indices[i] != j:
        break
    else:
      return
    j = indices[i]+1
    for i,j in zip(range(i,r), f(count(j), counts[j:])):
      indices[i] = j

用法:

>>> t = [2,2,2,2,4]
# elements in t must be hashable
>>> list(combinations_without_repetition(4, iterable=t)) 
[(2, 2, 2, 2), (2, 2, 2, 4)]

# You can pass values and counts separately. For this usage, values don't need to be hashable
# Say you have ['a','b','b','c','c','c'], then since there is 1 of 'a', 2 of 'b', and 3 of 'c', you can do as follows:
>>> list(combinations_without_repetition(3, values=['a','b','c'], counts=[1,2,3]))
[('a', 'b', 'b'), ('a', 'b', 'c'), ('a', 'c', 'c'), ('b', 'b', 'c'), ('b', 'c', 'c'), ('c', 'c', 'c')]

# combinations_without_repetition() is a generator (and thus an iterator)
# so you can iterate it
>>> for comb in combinations_without_repetition(4, t):
...   print(sum(comb))
...
8   # 2+2+2+2
10  # 2+2+2+4

请注意itertools.combinations()在C中实现,这意味着在大多数情况下它比我的python脚本快得多。只有当有多个重复组合而不是唯一组合时,此代码才能比set(itertools.combinations())方法更好。

答案 1 :(得分:5)

由于Donkey Kong指向设置,您可以通过将列表转换为集合来获取列表中的唯一值:

t = [2,2,2,2,4]
c = list(itertools.combinations(t, 4))
unq = set(c)
print(unq)

结果将是:

{(2, 2, 2, 4), (2, 2, 2, 2)}

如果要将其用作列表,可以通过执行以下操作将其转换回来:

result = list(unq)

替代性和更加干净,全面的方式将是:

t = [2,2,2,2,4]
c = set(itertools.combinations(t, 4))

答案 2 :(得分:5)

从技术上讲,如果您阅读链接页面中的说明,那么您获得的内容实际上并不重复,它只是itertools.combinations的工作原理:

  

itertools.combinations(iterable, r)

     

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

     

组合以字典排序顺序发出。因此,如果对输入iterable进行排序,则将生成组合元组   排序顺序。

     

根据元素的位置而不是元素将元素视为唯一元素。因此,如果输入元素是唯一的,那么就没有了   重复每个组合中的值。

样本:

>>> import itertools as it
>>> list(it.combinations([1,2,3,4,5], 4))
[(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]

因此,正如在上一个答案中发布的那样,set()会为您提供所需的唯一值:

>>> set(it.combinations(t, 4))
{(2, 2, 2, 4), (2, 2, 2, 2)}
相关问题