我正在使用Python 2.7。
我有一个列表,我想要所有可能的有序组合。
import itertools
stuff = ["a","b","c", "d"]
for L in range(1, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
print( ' '.join(subset))
这将提供以下输出:
a
b
c
d
a b
a c <-- not in correct order
a d <-- not in correct order
b c
b d <-- not in correct order
c d
a b c
a b d <-- not in correct order
a c d <-- not in correct order
b c d
a b c d
但我希望输出只是与stuff
列表顺序相同的组合。例如。移除a d
,b d
,a b d
和a c d
,因为与stuff
列表["a", "b", "c", "d"]
相比,这些订单的顺序不正确。
我已经想出了使用它:
import itertools
stuff = ["a","b","c", "d"]
for L in range(1, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
if ' '.join(subset) in ' '.join(stuff): #added line
print( ' '.join(subset))
给我输出我想要的输出:
a
b
c
d
a b
b c
c d
a b c
b c d
a b c d
但Python中是否有任何内置方法可以满足我的需求?
答案 0 :(得分:12)
我相信你要找的是原始列表的所有切片。您想要的输出转换为切片是这样的:
a # slices[0:1]
b # slices[1:2]
c # slices[2:3]
d # slices[3:4]
a b # slices[0:2]
b c # slices[1:3]
c d # slices[2:4]
a b c # slices[0:3]
b c d # slices[1:4]
a b c d # slices[0:4]
那么您应该尝试生成的是那些索引。如果仔细观察并对它们进行排序,您可以看到它们是0到4之间的2个数字组合,其中第一个数字小于另一个数字 - 这正是itertools.combinations
对于列表的索引。所以我们可以生成那些:
for i, j in itertools.combinations(range(len(stuff) + 1), 2):
print(stuff[i:j])
这会产生以下输出:
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['b']
['b', 'c']
['b', 'c', 'd']
['c']
['c', 'd']
['d']
这样做的好处是,它会生成输入的实际子列表,而不关心首先是单个字符的那些。它可以是列表中的任何类型的内容。
如果输出顺序具有任何重要性,您可以按输出列表大小排序以获得所需的结果:
def getCombinations (lst):
for i, j in itertools.combinations(range(len(lst) + 1), 2):
yield lst[i:j]
for x in sorted(getCombinations(stuff), key=len):
print(' '.join(x))
答案 1 :(得分:2)
我认为你的意思是按照正确的顺序按顺序排列&#34;,在这种情况下你只需要在stuff
上使用两个指向迭代器的指针:
stuff = ["a","b","c", "d"]
# sort stuff here if it's not sorted
result = []
for i in xrange(len(stuff)):
for j in xrange(i+1, len(stuff)+1):
result.append(stuff[i:j])
# sort the result by length, maybe you don't need it
result = sorted(result, key=len)
for r in result:
print ' '.join(r)