以多种方式合并2个列表Python

2024-09-30 05:30:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经尝试了很多技巧,但我相信有一个平滑的方法来完成这个任务。在

假设我有两个列表,其中包含相同数量的项目(每个4个):

a = ['a', 'b', 'c', 'd']    
b = [1, 2, 3, 4]

在保持秩序的同时,我想用所有可能的方式合并这些列表。输出示例:

^{pr2}$

关键是每个列表都必须保持其顺序,这样考虑到一个项在列表中的位置,它就不能位于输出中的另一个项之前。例如,输出不能是:

a, b, **d**, c, 1...   > d precedes c whereas c is before d in the original list
1, **4**, a, b, 3....  > 4 precedes 3 whereas 3 is before 4 in the original list

我想我们的想法是用所有可能的方法将第二个列表合并到第一个列表中。一个充分发挥作用的例子是:

a = [a, b]    
b = [1, 2]

期望输出:

ab12                                                                      
a1b2                                                                             
a12b                                                                         
1ab2                                                                             
1a2b                                                                          
12ab

我该怎么做?itertools是否有能力以某种方式做到这一点?或者有别的方法可以完成吗?请帮忙!在


Tags: the项目方法in列表技巧数量is
3条回答

使用python的递归方法:

def f( s , l1 , l2 ):
        if( l1 == [] and l2 == [] ):
                print s
                return
        if( l1 != [] ):
                f( s + l1[0] , l1[1:] , l2 )
        if( l2 != [] ):
                f( s + str(l2[0]) , l1 , l2[1:] )

一种选择是使用一个计数器,其中set bits对应于a上的item,而unset则对应于b上的item。对于计数器中的每个值,检查是否设置了len(a)位并生成一个排列:

def ordered_permutations(l1, l2):
    length = len(l1) + len(l2)
    fmt = '{{0:0{0}b}}'.format(length)

    for i in xrange(2 ** length):
        seq = fmt.format(i)

        if seq.count('1') == len(l1):
            iters = [iter(l1), iter(l2)]
            yield [iters[int(c)].next() for c in seq]

用法:

^{2}$

输出:

['a', 'b', 1, 2]
['a', 1, 'b', 2]
['a', 1, 2, 'b']
[1, 'a', 'b', 2]
[1, 'a', 2, 'b']
[1, 2, 'a', 'b']

可以通过使用HAKMEM 175来生成下一个序列,而不是使用计数器和检查是否设置了正确的位,从而改进了实现。在

在2x4的情况下,您希望在不中断每个四边形内的顺序的情况下获取所有8个元素。这些例子:

a, b, c, d, 1, 2, 3, 4    
1, 2, 3, 4, a, b, c, d    
a, b, 1, 2, c, 3, 4, d

可以转换为“指令”序列,这些指令是从0或1中获取的列表:

^{2}$

一旦您意识到这一点,您可能会注意到我们需要生成的序列都是由4个0和4个1组成的排列。完成这一飞跃后,我们可以使用itertools

itertools.permutations([0,0,0,0,1,1,1,1])

对于2x4的情况,这给出了40320个结果,但只有70个唯一的结果(因为itertools.permutations认为1,1,1与1,1,1不同,如果数字被重新排序)。你可以从这里的答案中得到唯一的排列:https://stackoverflow.com/a/6285330/4323或者只使用set()。在


综上所述,这里有一个完整的解决方案:

import itertools

def combos(*seqs):
    counts = map(len, seqs)
    base = []
    for ii, count in enumerate(counts):
        base.extend([ii]*count)
    for take in set(itertools.permutations(base)):
        result = []
        where = [0] * len(seqs)
        for elem in take:
            result.append(seqs[elem][where[elem]])
            where[elem] += 1
        yield result

你可以这样测试(给出70个结果):

a = ['a', 'b', 'c', 'd']
b = [1, 2, 3, 4]

for res in combos(a, b):
    print res

相关问题 更多 >

    热门问题