python:奇怪的列表元素组合

时间:2012-05-18 15:08:23

标签: python list combinations

我有以下两个清单:

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的顺序很重要。 我正在努力解决这个问题。任何帮助表示赞赏。

5 个答案:

答案 0 :(得分:4)

这样做的一种方法是使用itertools.combinations来挑选最终列表的索引,并将l1的元素放入其中。然后,对于每个选项,使用itertools.permutations查找第二个列表中项目的所有排列。然后浏览这两个列表,取决于索引是否应该是l1l2元素的索引。

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