在python中修改的排列

时间:2014-02-19 20:22:26

标签: python permutation

我坚持以下问题: 有正常的排列函数:

def all_perms(elements):
    if len(elements) <=1:
        yield elements
    else:
        for perm in all_perms(elements[1:]):
            for i in range(len(elements)):
                yield perm[:i] + elements[0:1] + perm[i:]

我在这里得到了预期的

for pz in all_perms([1,2,3]):
    print(pz)

[1, 2, 3]
[2, 1, 3]
[2, 3, 1]
[1, 3, 2]
[3, 1, 2]
[3, 2, 1]

然后我有简单的反向功能:

def reverse(rx):
    return -rx

如果假设每个元素必须被反转,那么看看perm_rev(iterable)函数如何导致置换? [1,2]的答案是这样的:

for pz in perm_rev([1,2]):
    print(pz)

[1,2]
[2,1]
[-1,2]
[1,-2]
[-2,1]
[2,-1]
[-1,-2]
[-2,-1]

谢谢!

2 个答案:

答案 0 :(得分:1)

import itertools as IT
def perm_rev(iterable):
    for grp in IT.product(*[[x, -x] for x in iterable]): # 1
        for item in IT.permutations(grp):                # 2
            yield item

例如,

In [46]: list(perm_rev([1,2]))
Out[46]: [(1, 2), (2, 1), (1, -2), (-2, 1), (-1, 2), (2, -1), (-1, -2), (-2, -1)]
  1. 对于x中的每个iterablegrp会选择x-x。对于 例如,

    In [53]: list(IT.product([-1,1], [-2,2])) 
    Out[53]: [(-1, -2), (-1, 2), (1, -2), (1, 2)]
    
  2. 然后,对于每个grp,生成grp
  3. 的permutions

    另请注意,您的all_perms可以使用itertools.permutations

    来撰写
    def all_perms(elements):
        return IT.permutations(elements)
    

    两者基本相同(除了元素的顺序,IT.permutations返回迭代器而不是列表)。


    要概括perm_rev以应用reverse以外的功能,您可以这样做:

    def reverse(x):
        return [x, -x]
    
    def perm_rev(iterable, options):
        for grp in IT.product(*[options(x) for x in iterable]): 
            for item in IT.permutations(grp):                
                yield item
    

    然后,像这样呼叫perm_rev

    In [58]: list(perm_rev([1,2], reverse))
    Out[58]: [(1, 2), (2, 1), (1, -2), (-2, 1), (-1, 2), (2, -1), (-1, -2), (-2, -1)]
    

答案 1 :(得分:0)

使用itertools.product() call

在生成器函数中添加反转
def perm_rev(seq):
    for perm in permutations(seq):
        for prod in product(*((i, -i) for i in perm)):
            yield prod

演示:

>>> for pz in perm_rev([1,2]):
...     print(pz)
... 
(1, 2)
(1, -2)
(-1, 2)
(-1, -2)
(2, 1)
(2, -1)
(-2, 1)
(-2, -1)