我坚持以下问题: 有正常的排列函数:
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 :(得分: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)]
对于x
中的每个iterable
,grp
会选择x
或-x
。对于
例如,
In [53]: list(IT.product([-1,1], [-2,2]))
Out[53]: [(-1, -2), (-1, 2), (1, -2), (1, 2)]
grp
,生成grp
。另请注意,您的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)
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)