我有以下两个清单:
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
的顺序很重要而l2
的顺序不重要。 l2
个元素在l1 + l2个位置上运行,但只有l1
的顺序很重要。
我正在努力解决这个问题。任何帮助表示赞赏。
答案 0 :(得分: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]
答案 1 :(得分: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正确实现的(它比这项技术更有效)
答案 2 :(得分:1)
我认为,解决此问题的更好方法之一是保持[1,2,3]不变,然后,对于'x',识别可以插入四个位置(在'1之前) ',在'2'之前,......在'3'之后)。然后,一旦插入'x',现在有5个位置插入'y'(三个未插入'x',加上'x'之前和'x'之后)。使用嵌套循环在每个可能的位置插入“x”和“y”。作为奖励,将嵌套循环提炼为理解......
答案 3 :(得分: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']
答案 4 :(得分: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]]