简体   繁体   English

python中所有可能的列表合并

[英]All possible merges of lists in python

I would like to get all the possible ways to merge 2 (or ideally n) lists in python, while maintaining each list's internal order - ie I would like to find some function all_merges that would behave like this: 我想获得所有可能的方式来在python中合并2个(或理想情况下为n个)列表,同时保持每个列表的内部顺序-即,我想找到一些功能类似于all_merges的行为:

a = all_merges([1,2],[3,4]) 

results in: 结果是:

a = [
[1,2,3,4],
[1,3,2,4],
[1,3,4,2],
[3,1,2,4],
[3,1,4,2],
[3,4,1,2]   ]

(I hope this is all of them) (我希望这就是全部)

I cannot find simple, 'pythonic' way to do this - please help! 我找不到执行此操作的简单“ pythonic”方法-请帮助!

===== =====

Note: 注意:

I am considering something like this (written to be relatively readable): 我正在考虑这样的东西(被编写为相对可读):

from itertools import permutations
def all_merges(list1,list2):
    a = [1]*len(list1)
    b = [2]*len(list2)
    indexes = list(set(list(permutations(a+b))))
    lists = [[]]*3
    res = indexes # just for readability, will be overwriting indexes as we go along
    for perm in indexes:
        lists[1] = copy(list1)
        lists[2] = copy(list2)
        merge = perm
        for i in range(0,len(perm)):
            merge[j] = lists[perm[i]].pop(0)
    return res

however at the stage 但是在现阶段

list(set(list(permutations(a+b))

if the combined length of the lists is so much as 15 I get a huge amount of results from 如果列表的总长度多达15个,我将从中获得大量结果

permutations(a+b)

(15!, to be precise), whereas at most I will only really have 15choose7 (= 6435) different merges. (精确到15!),而至多我最多只会真正有15choose7(= 6435)个不同的合并。

I realise a replacement to that line is provided here, as a function: permutations with unique values but by now this is getting messy and I want to see if there is a cleaner solution to my original problem. 我意识到这里可以作为功能替换该行: 具有唯一值的置换,但是现在这变得混乱了,我想看看是否有更干净的解决方案来解决我的原始问题。

Each possible merge corresponds directly to one of (len(a) + len(b)) choose len(a) ways to pick len(a) positions for the elements of a in the final list: 每个可能的合并都直接对应于(len(a) + len(b)) choose len(a)方式为最终列表中a的元素选择len(a)位置:

import itertools
def all_merges(a, b):
    # object guaranteed not to be in either input list
    sentinel = object()
    merged_length = len(a) + len(b)
    for a_positions in itertools.combinations(xrange(merged_length), len(a)):
        merged = [sentinel] * merged_length

        # Place the elements of a in their chosen positions.
        for pos, a_elem in zip(a_positions, a):
            merged[pos] = a_elem

        # Place the elements of b in the positions not taken.
        b_iter = iter(b)
        for pos in xrange(merged_length):
            if merged[pos] is sentinel:
                merged[pos] = next(b_iter)

        yield merged

This can be extended to more lists in several ways, such as by using some technique (perhaps Algorithm L ) to go through all ways to assign positions to list elements, or by applying the 2-way merge repeatedly. 可以通过几种方式将其扩展到更多列表,例如使用某种技术(也许是算法L )通过所有方式将位置分配给列表元素,或者通过反复应用2向合并。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM