我需要获得排列,排除镜像序列,即应包括(1,0,4),但应排除(4,0,1)。 我想出了以下功能,但想知道是否有更简单的解决方案。
该函数基于它们的最后一个元素与相应序列的第一个元素相同的事实跳过反转,该元素已经按照字典顺序处理。
def permutations_no_inverse(iterable):
"""Return the half of permutations, treating mirrored sequences as the same,
e.g. (0, 1, 2) and (2, 1, 0) are the same.
Assume itertools.permutations returns tuples
"""
all_perm = it.permutations(iterable)
cur_start = None
starts_processed = set()
for perm in all_perm:
new_start = perm[0]
if new_start != cur_start:
if cur_start != None:
starts_processed.add(cur_start)
cur_start = new_start
if perm[-1] in starts_processed:
continue
else:
yield perm
答案 0 :(得分:2)
假设iterable
中的条目是唯一且可订购的,我只需比较排列的任何两个元素(例如第一个和最后一个),并且仅包括第一个元素小于或等于的排列。最后一个元素。这样,您就不需要存储已经看过的内容,也不关心itertools.permutations()
返回排列的顺序。
示例代码:
def permutations_no_inverse(iterable):
for p in itertools.permutations(iterable):
if p[0] <= p[-1]:
yield p
答案 1 :(得分:0)
您的问题已经明确说明...wondering whether there is simpler solution
,我认为下面的问题很简单:
def permutations_no_inverse(iterable):
found_items = []
for p in it.permutations(iterable):
if p not in found_items:
found_items.extend([p, p[::-1]])
else:
yield p
答案 2 :(得分:0)
基于python延迟了最新列的反转元组排序这一事实,我们可以设想将排列设置为一个统一矩阵,然后将其对角划分,以获得矩阵的未镜像部分。
k=[1, 2, 3,4]
l=itertools.permutations(k)
a=list(l)
b=np.array(a).reshape((len(k),len(a)/len(k),len(k)))
neat_list=np.flipud(b)[np.tril_indices(len(k))]
这应该对我猜的所有数组长度都有效....
使用k=[1,2,3,4,5,6]
打印
array([
[6, 1, 2, 3, 4, 5],
[5, 1, 2, 3, 4, 6],
[5, 1, 2, 3, 6, 4],
[4, 1, 2, 3, 5, 6],
[4, 1, 2, 3, 6, 5],
[4, 1, 2, 5, 3, 6],
[3, 1, 2, 4, 5, 6],
[3, 1, 2, 4, 6, 5],
[3, 1, 2, 5, 4, 6],
[3, 1, 2, 5, 6, 4],
[2, 1, 3, 4, 5, 6],
[2, 1, 3, 4, 6, 5],
[2, 1, 3, 5, 4, 6],
[2, 1, 3, 5, 6, 4],
[2, 1, 3, 6, 4, 5],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 6, 5],
[1, 2, 3, 5, 4, 6],
[1, 2, 3, 5, 6, 4],
[1, 2, 3, 6, 4, 5],
[1, 2, 3, 6, 5, 4]])
我试过了:
test=[list(g) for g in neat_list]
any([(u[::-1] in test) for u in test])
这会输出false
,这意味着没有反转阵列的出现。