所以,我开始使用这个数组:
array = ['A', 'B', 'C', 'D', 'E', 'F']
在让python打印每个独特的非重复组合之前,我玩了一会儿,如下所示:
AB,
AC,
AD,
AE,
AF,
BC,
BD,
BE,
BF,
CD,
CE,
CF,
DE,
DF,
EF,
但是现在,我想将所有这些变成一个新阵列:
array2 = ['AB', 'AC', 'AD'...., 'EF']
打印所有没有重复的3元素长组合,不包括重排。
我的意思是'没有重复':
AB
,CD
和EF
是一个3元素的长组合,没有重复,但AB
,BD
和EF
是一个3元素长的重复组合,'B'
出现在' AB'和' BD'
。
我的意思是'不包括重新排列':
AB,CD,EF与BA,DC,FE相同,因为所有2个字母的元素都相同(BA重新排列AB,DC重新排列CD,FE重新排列EF)。理想情况下,它打印的内容如下:
AB CD EF,
AB CE DF,
AB CF DE,
AC BD EF,
AC BE DF,
AC BF DE,
AD BC EF,
AD BE CF,
AD BF CE,
AE BC DF,
AE BD CF,
AE BF CD,
AF BC DE,
AF BD CE,
AF BE CD,
我相信这些都是没有重复2个字母元素的组合。
我该如何打印?谢谢!
答案 0 :(得分:2)
Generator的递归方法(没有任何itertools):
def comb(s):
if len(s) == 2:
yield [s]
for x in s[1:]:
first = ''.join((s[0], x))
rest = ''.join(c for c in s if c not in first)
for com in comb(rest):
yield [first] + com
>>> list(comb('ABCDEF'))
[['AB', 'CD', 'EF'],
['AB', 'CE', 'DF'],
['AB', 'CF', 'DE'],
['AC', 'BD', 'EF'],
['AC', 'BE', 'DF'],
['AC', 'BF', 'DE'],
['AD', 'BC', 'EF'],
['AD', 'BE', 'CF'],
['AD', 'BF', 'CE'],
['AE', 'BC', 'DF'],
['AE', 'BD', 'CF'],
['AE', 'BF', 'CD'],
['AF', 'BC', 'DE'],
['AF', 'BD', 'CE'],
['AF', 'BE', 'CD']]
这将获取第一个元素,将其与每个其他元素配对,并将结果对与可以从其余元素制作的每个穷举对列表组合。基本情况是只有两个元素。
注意: rest
的汇编预先假定初始字符串/序列中没有重复。
答案 1 :(得分:1)
这是使用itertools
的强力非递归版本。它生成对,然后使用集合来制作这些对的所有组合,以消除重复任何字母的组合。它比combinations
非常快。
from itertools import combinations
def pairs(s):
n = len(s)
numgroups = n // 2
for v in combinations(map(''.join, combinations(s, 2)), numgroups):
if len(set(i for u in v for i in u)) == n:
yield v
for t in pairs('ABCDEF'):
print(t)
<强>输出强>
('AB', 'CD', 'EF')
('AB', 'CE', 'DF')
('AB', 'CF', 'DE')
('AC', 'BD', 'EF')
('AC', 'BE', 'DF')
('AC', 'BF', 'DE')
('AD', 'BC', 'EF')
('AD', 'BE', 'CF')
('AD', 'BF', 'CE')
('AE', 'BC', 'DF')
('AE', 'BD', 'CF')
('AE', 'BF', 'CD')
('AF', 'BC', 'DE')
('AF', 'BD', 'CE')
('AF', 'BE', 'CD')
在我的2GHz机器上,打印pairs('ABCDEFGHIJ')
的945结果大约需要13秒。相比之下,schwobaseggl的comb
只需要0.193秒。 :)
这是一个更智能的itertools版本。这个仍然比必要的工作更多,但它只是schwobaseggl的comb
发生器的两倍慢。我们首先生成原始字符串大小的一半的组合,并使用set.difference
来生成互补组合。然后我们将该组合置换为与原始组合相结合。
from itertools import combinations, permutations
def pairs(s):
a = set(s)
for u in combinations(s, len(s) // 2):
b = tuple(sorted(a.difference(u)))
if b < u:
break
for v in permutations(b):
c = [*zip(u, v)]
if all(i<j for i, j in c):
yield [*map(''.join, c)]
答案 2 :(得分:0)
PM 2Ring代码的更快变化:
from itertools import combinations
array = ['A', 'B', 'C', 'D', 'E', 'F']
n = len(array)
numgroups = n // 2
array2 = map(''.join, combinations(array,2))
result = (' '.join(com) for com in combinations(array2,numgroups) if len(set(''.join(com)))==n)
for res in result:
print res