Python:生成列表的所有有序组合

发布于 2021-01-29 14:58:23

我正在使用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 db da 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
被浏览
86
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我相信您正在寻找的是原始列表中的所有可能 片段 。您所需的输出转换成切片是这样的:

    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))
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看