如何按条件排除itertools排列的某些结果?

时间:2019-06-22 12:29:27

标签: python permutation

我正在尝试解决Rosalind的问题。

  

返回:长度为n的带符号排列的总数,后跟列表   所有此类排列(您可以按任何顺序列出已签名的排列)。

我有一个使用Python解决方案的想法,但是我无法实现它。例如,考虑n = 2。

    numbers = [1, -1, 2, -2]
    ordering = permutations(numbers,n)

所以现在我得到了一些元组:

  

(1,-1)(1,2)(1,-2)(-1,1)(-1,2)(-1,-2)(2,1)(2,-1) (2,-2)(-2,1)   (-2,-1)(-2,2)

我需要排除那些具有相同模量的元素。例如,(-1,1)。有可能实现这一目标吗?如果可能的话,如何实现?

3 个答案:

答案 0 :(得分:2)

使用列表理解的 pythonic 解决方案:

filtered_perms = [(x,y) for x,y in ordering if abs(x) != abs(y)] 

编辑: 可以在python 3.7上正常工作的代码:

import itertools as itt

# create permutation generator object
perms = itt.permutations([-2, -1, 1, 2], 2)  

# here generator is turned into a list with certain permutations excluded
filtered_perms = [(x,y) for x,y in perms if abs(x) != abs(y)]

# print whole list
print(filtered_perms) 

# print first permutation
print(filtered_perms[0])

# print length of the list
print(len(filtered_perms))

Edit2: 要解决ordering中没有任何元素的问题:

ordering = list(itertools.permutations([-2, -1, 1, 2],2))

之后,排序将是itertools.permutations中所有元素的列表。

答案 1 :(得分:0)

您可能正在寻找filter函数。

list(filter(lambda pair: abs(pair[0]) != abs(pair[1]), ordering))

条件可能是错误的,我不确定相等模量是什么意思。

答案 2 :(得分:0)

之前提出的解决方案是正确的,但是如果要在生成排列后处理结果列表,则最好使用生成器而不是列表。为此,我建议您基于itertools.permutations设计自己的生成器函数:

def signed_permutations(iterable, r=2):
    for item in permutations(iterable, r):
        if abs(item[0]) != abs(item[1]):
            yield item

您可以将其用作:

for item in signed_permutations(numbers):
    do_something(item)

或者,如果您只想创建列表:

sigperm = list(signed_permutations(numbers))