2014-02-19 92 views
0

我被困在下面的問題: 有正常的置換函數:排列組合與蟒蛇修改

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] 

謝謝!

+0

@Martijn皮特斯和unutbu:謝謝你,但我需要使用反轉功能(這裏簡化了)。實際上,反向必須是修改元素的任何函數。元素可以是一個列表。 – pro100

回答

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. 對於iterable中的每個x,grp選擇x-x。對於 例如,

    In [53]: list(IT.product([-1,1], [-2,2])) 
    Out[53]: [(-1, -2), (-1, 2), (1, -2), (1, 2)] 
    
  2. 然後,對於每個grp,生成的grp的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)] 
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) 
+0

這包括'[1,-1]' – simonzack

+0

@simonzack:已更正。 –