2017-01-11 152 views
-1

给定一个列表,我想要所有的排列长度,但只有那些保持排序的排列。如何在Python中获取列表的所有排序列表

因此,如果该列表是

[1,1,3,4] 

然后用长度为2答案是

[[1,1], [1,1], [1,3], [1,3] [3,4], [1,4], [1,4]] 

请提供一个有效的答案。

+0

为什么你'[1,3]'两次,但'[1,1]'只有一次?你想如何处理重复? –

+0

所以你不想删除重复?然后由@Inbar的答案是非常好的。只要'排序(r)'而不是先铸造到'set'。 –

回答

6
import itertools 

l = [1, 1, 3, 4] 
r = [perm for perm in itertools.permutations(l, 2) if sorted(perm) == list(perm)] 

结果:

[(1, 1), (1, 3), (1, 4), (1, 1), (1, 3), (1, 4), (3, 4)] 

如果你想要的结果排序,和独特:

s = sorted(set(r)) # [(1, 1), (1, 3), (1, 4), (3, 4)] 

如果你想要的结果列表而不是元组,只投他们作为list()


使用了itertools.permutations我为你做这个方便的功能配方:

def sorted_perms(iterable, r=None): 
    pool = tuple(sorted(iterable)) 
    n = len(pool) 
    r = n if r is None else r 
    for indices in itertools.product(range(n), repeat=r): 
     if len(set(indices)) == r and tuple_is_sorted(indices): 
      yield tuple(pool[i] for i in indices) 

memo = {} # simple memoization for efficiency. 
def tuple_is_sorted(t): 
    return memo.setdefault(t, bool(sorted(t) == list(t))) 

r = list(sorted_perms(l, 2)) # [(1, 1), (1, 3), (1, 4), (1, 3), (1, 4), (3, 4)] 
s = sorted(set(r)) # [(1, 1), (1, 3), (1, 4), (3, 4)] 
+0

然后Python会实际计算所有排列,然后删除所有未排序的排列?这不是那种低效率吗? –

+0

@ImeanH它会的,理论上它是低效的,但你有什么其他的好选择? –

+0

@ImeanH在答案中,我给出了答案,那就是它会做的,这是OP中的问题。 –

0

您可以使用itertools.permutationsoperator.le过滤

import itertools 
import operator 

l = [1, 1, 3, 4] 

unique = filter(lambda x: operator.le(x[0], x[1]), itertools.permutations(l, 2)) 

print(sorted(unique)) 

输出

[(1, 1), (1, 1), (1, 3), (1, 3), (1, 4), (1, 4), (3, 4)] 

它转换为列表

print([[a, b] for a, b in sorted(unique)]) 

输出

[[1, 1], [1, 1], [1, 3], [1, 3], [1, 4], [1, 4], [3, 4]]