9

我有以下两个列表:

l1 = [1, 2, ,3]  
l2 = [x, y]  

并希望所有 5 个元素的列表l1仅保持顺序。说:

[x, y, 1, 2, 3],  
[x, 1, y, 2, 3],  
[x, 1, 2, y, 3],  
[x, 1, 2, 3, y],  
[y, x, 1, 2, 3],  
[y, 1, x, 2, 3],  
[y, 1, 2, x, 3],  
[y, 1, 2, 3, x],  
[1, x, y, 2, 3],  
[1, x, 2, y, 3],  
[1, x, 2, 3, y],  
[1, y, x, 2, 3],  
[1, y, 2, x, 3],  
[1, y, 2, 3, x],  
...  
[1, 2, 3, y, x],  
...  
[1, 2, 3, x, y]  

请注意,顺序l1很重要,但不重要l2l2元素在 l1+l2 位置上运行,但只有顺序l1很重要。我正在为此苦苦挣扎。任何帮助表示赞赏。

4

5 回答 5

4

我称之为散布 l1 与(l2 的排列)。您可以分两步执行此操作:选择位置,然后排列位置。对于插入点,您可以使用基于掩码的方法 ( permutations([True,True,False,False,False])) 或基于索引的方法 ( product(*[range(5)]*2))。还没有使后一种技术起作用。

from itertools import *

def interspersings(l1,l2):
    for mask in set(permutations([0]*len(l1) + [1]*len(l2))):  # sadly inefficient
        iters = [iter(l1), iter(l2)]
        yield [next(iters[which]) for which in mask]

for perm in permutations(l2):
    for interspersing in interspersings(l1,perm):
        print(interspersing)

演示:

[1, 2, 'x', 'y', 3]
['x', 'y', 1, 2, 3]
[1, 2, 'x', 3, 'y']
[1, 2, 3, 'x', 'y']
['x', 1, 'y', 2, 3]
[1, 'x', 'y', 2, 3]
[1, 'x', 2, 'y', 3]
['x', 1, 2, 'y', 3]
[1, 'x', 2, 3, 'y']
['x', 1, 2, 3, 'y']
[1, 2, 'y', 'x', 3]
['y', 'x', 1, 2, 3]
[1, 2, 'y', 3, 'x']
[1, 2, 3, 'y', 'x']
['y', 1, 'x', 2, 3]
[1, 'y', 'x', 2, 3]
[1, 'y', 2, 'x', 3]
['y', 1, 2, 'x', 3]
[1, 'y', 2, 3, 'x']
['y', 1, 2, 3, 'x']

编辑:啊,我提到的后一种技术是由 Mark Longair 在https://stackoverflow.com/a/10655695/711085正确实现的(它比这种技术效率更高)

于 2012-05-18T15:48:52.057 回答
4

这样做的一种方法是使用itertools.combinations选择最终列表的索引,您将在其中放入l1. 然后,对于这些选择中的每一个,使用itertools.permutations来查找第二个列表中项目的所有排列。然后遍历这两个列表,根据索引是否应该是用于元素的索引,从前面的任何一个中挑选l1出来l2

from itertools import combinations, permutations

l1 = [1, 2, 3]
l2 = ["x", "y"]

n = len(l1) + len(l2)

for c in combinations(range(0, n), len(l1)):
    cs = set(c)
    for p in permutations(l2):
        l1i = iter(l1)
        l2i = iter(p)
        print [ l1i.next() if i in cs else l2i.next() for i in range(0,n) ]

输出将是:

[1, 2, 3, 'x', 'y']
[1, 2, 3, 'y', 'x']
[1, 2, 'x', 3, 'y']
[1, 2, 'y', 3, 'x']
[1, 2, 'x', 'y', 3]
[1, 2, 'y', 'x', 3]
[1, 'x', 2, 3, 'y']
[1, 'y', 2, 3, 'x']
[1, 'x', 2, 'y', 3]
[1, 'y', 2, 'x', 3]
[1, 'x', 'y', 2, 3]
[1, 'y', 'x', 2, 3]
['x', 1, 2, 3, 'y']
['y', 1, 2, 3, 'x']
['x', 1, 2, 'y', 3]
['y', 1, 2, 'x', 3]
['x', 1, 'y', 2, 3]
['y', 1, 'x', 2, 3]
['x', 'y', 1, 2, 3]
['y', 'x', 1, 2, 3]
于 2012-05-18T15:41:40.583 回答
1

我认为解决这个问题的更好方法之一是保持 [1,2,3] 原样,然后对于“x”,认识到可以插入四个位置(在“1”之前,之前'2', ... 在 '3' 之后)。然后,一旦插入了“x”,现在有 5 个位置可以插入“y”(未插入“x”的三个位置,加上“x”之前和“x”之后)。使用嵌套循环在每个可能的位置插入“x”和“y”。作为奖励,将嵌套循环提炼成理解......

于 2012-05-18T15:32:25.790 回答
0
>>> import itertools
>>> l1 = [1, 2, 3]
>>> l2 = ['x', 'y', 0, 0, 0]
>>> l4 = []
>>> cyc = itertools.cycle(l1)
>>> for el in set(itertools.permutations(l2, 5)):
...     l4.append([cyc.next() if j==0 else j for j in el])

产生:

>>> l4
[[1, 2, 'x', 3, 'y'], 
 ['y', 'x', 1, 2, 3], 
 ['x', 1, 'y', 2, 3], 
 ['x', 1, 2, 'y', 3], 
 [1, 2, 3, 'y', 'x'], 
 [1, 'y', 2, 3, 'x'], 
 [1, 2, 3, 'x', 'y'], 
 [1, 'x', 2, 3, 'y'], 
 [1, 'y', 'x', 2, 3], 
 [1, 2, 'x', 'y', 3], 
 [1, 2, 'y', 'x', 3], 
 [1, 'x', 2, 'y', 3], 
 ['y', 1, 2, 'x', 3], 
 ['x', 1, 2, 3, 'y'], 
 [1, 'y', 2, 'x', 3], 
 [1, 'x', 'y', 2, 3], 
 ['y', 1, 2, 3, 'x'], 
 ['x', 'y', 1, 2, 3], 
 [1, 2, 'y', 3, 'x'], 
 ['y', 1, 'x', 2, 3]]
于 2012-05-18T16:23:12.717 回答
0

我尝试使用 l1 的类占位符进行一些操作,itertools.permutations但其中有重复项。

所以,再试一次,这是我能得到的最简单的:

from itertools import combinations, permutations

l1 = [1, 2, 3]
l2 = ["x", "y"]
r = range(len(l1)+len(l2))
for combo in combinations(r,len(l2)):
  for permu in permutations(l2):
    i1 = iter(l1).next
    i2 = iter(permu).next
    row = [ i2() if i in combo else i1() for i in r ]
    print row

产量:

['x', 'y', 1, 2, 3]
['y', 'x', 1, 2, 3]
['x', 1, 'y', 2, 3]
['y', 1, 'x', 2, 3]
['x', 1, 2, 'y', 3]
['y', 1, 2, 'x', 3]
['x', 1, 2, 3, 'y']
['y', 1, 2, 3, 'x']
[1, 'x', 'y', 2, 3]
[1, 'y', 'x', 2, 3]
[1, 'x', 2, 'y', 3]
[1, 'y', 2, 'x', 3]
[1, 'x', 2, 3, 'y']
[1, 'y', 2, 3, 'x']
[1, 2, 'x', 'y', 3]
[1, 2, 'y', 'x', 3]
[1, 2, 'x', 3, 'y']
[1, 2, 'y', 3, 'x']
[1, 2, 3, 'x', 'y']
[1, 2, 3, 'y', 'x']
于 2012-05-18T15:27:58.547 回答