2013-05-27 175 views
1

我正在做一个输入一系列数字的程序,并将其中的6个数字作为彩票号码的不同组合。当我创建不同的组合时,我想删除重复项,以便每个组合只打印一次。 这是我希望发生的:在Python中删除重复列表

combo_list = [1 2 3 4 5 6 7] 

和输出应该是:

1 2 3 4 5 6 
1 2 3 4 5 7 
1 2 3 4 6 7 
1 2 3 5 6 7 
1 2 4 5 6 7 
1 3 4 5 6 7 
2 3 4 5 6 7 

我正在使用的代码是:

final = [] 
    for sublist in combo_list: 
     if sublist not in final: 
      final.append(sublist) 
    for item in final: 
     item = (sorted(item, key=int)) 
     print (' '.join(str(n) for n in item)) 

不过,我得到的输出当我使用代码时有很多重复项:

1 2 3 4 5 6 
1 2 3 4 5 7 
1 2 3 4 5 6 
1 2 3 4 6 7 
1 2 3 4 5 7 
1 2 3 4 6 7 
1 2 3 4 5 6 
1 2 3 4 5 7 
1 2 3 4 5 6 
1 2 3 5 6 7 
1 2 3 4 5 7 
1 2 3 5 6 7 
1 2 3 4 5 6 
1 2 3 4 6 7 
1 2 3 4 5 6 
1 2 3 5 6 7 
1 2 3 4 6 7 
1 2 3 5 6 7 
1 2 3 4 5 7 
1 2 3 4 6 7 
1 2 3 4 5 7 
1 2 3 5 6 7 
1 2 3 4 6 7 
1 2 3 5 6 7 
1 2 3 4 5 6 
. 
. 
. 

任何想法,我必须改变每个组合只能打印一次?

+0

您的算法似乎有缺陷 - 你没有接近问题的权利。已知组合的数量,python作为[itertools](http://docs.python.org/2/library/itertools.html)库以更高效的方式处理此问题。 – 2013-05-27 02:38:45

+0

想想你是否可以修改你的代码,以便不首先生成重复项。 –

回答

5

使用itertools.combinations()此:

import itertools as it 
ans = it.combinations([1, 2, 3, 4, 5, 6, 7], 6) 

结果是理所应当的:

list(ans) 

=> [(1, 2, 3, 4, 5, 6), (1, 2, 3, 4, 5, 7), 
    (1, 2, 3, 4, 6, 7), (1, 2, 3, 5, 6, 7), 
    (1, 2, 4, 5, 6, 7), (1, 3, 4, 5, 6, 7), 
    (2, 3, 4, 5, 6, 7)] 

如果您需要事后打印的数字很容易:

for r in ans: 
    print ' '.join(str(s) for s in r) 

=> 1 2 3 4 5 6 
    1 2 3 4 5 7 
    1 2 3 4 6 7 
    1 2 3 5 6 7 
    1 2 4 5 6 7 
    1 3 4 5 6 7 
    2 3 4 5 6 7 
+0

这是非常有用的,但我应该澄清;我被要求使用递归来解决这个问题(我这样做),所以最后一步是消除重复。有没有其他的itertools函数? – user1778344

+0

@ user1778344在您发布的代码中没有使用递归。无论如何,如果你想从清单列表中删除重复项,将其转换为一组元组:set(最后x的元组(tuple(x))) –

+0

@ÓscarLópez你也可以让数字字符串开始,所以你不需要稍后转换它们 – jamylak

0

如果我理解你的问题,继续尝试使用combinations函数从itertools模块。在你的情况,你会得到:

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

这是我认为你想要的。

请记住,combinations函数的输出是一个生成器。

+1

另外,如果您有兴趣,itertools中组合函数的文档给出了该算法的纯Python实现。 – 2013-05-27 02:42:50

0

你可以只取源itertools.combinations则:

def lotto(iterable, r): 
    pool = tuple(iterable) 
    n = len(pool) 
    if r > n: 
     return 
    indices = range(r) 
    yield tuple(pool[i] for i in indices) 
    while True: 
     for i in reversed(range(r)): 
      if indices[i] != i + n - r: 
       break 
     else: 
      return 
     indices[i] += 1 
     for j in range(i+1, r): 
      indices[j] = indices[j-1] + 1 
     yield tuple(pool[i] for i in indices) 

print list(lotto([1, 2, 3, 4, 5, 6, 7], 6)) 
+0

OP表示解决方案必须是递归的(即使他的解决方案不是递归的) –

+0

对不起,我缩写了我的代码,因为它很长。我只在主函数中发布了最后几个步骤。到那时,这些组合已经被递归地创建了。 – user1778344

0

根据您的愿望,简单地删除重复..使用Python set

final = [] 
    for sublist in combo_list: 
     if sublist not in final: 
      final.append(sublist) 
    for item in set(tuple(x) for x in final): 
     item = (sorted(item, key=int)) 
     print (' '.join(str(n) for n in item)) 

但FWIW - 为什么重新创建轮使用@ÓscarLópez答案;)

HTH

+0

列表不可排除。请参阅我的回答中的最后一条评论:在最后一个循环中,OP需要做的事情是'为集合中的项目(元组(x)为最终的x)' –

+0

是的 - 你是对的! – rh0dium

0
comb_list= range(1, 8) 
rip_idx = 6 
for idx in range(len(comb_list)): 
    final = comb_list[0:rip_idx -idx ] + comb_list[rip_idx- idx + 1: ] 
    print final 

一个简单的方法来实现它解决没有任何库