如何在不“移动”零的情况下生成列表的排列.在Python中

使用itertools工具,我有给定的数字列表的所有可能的排列,但如果列表如下:

List=[0,0,0,0,3,6,0,0,5,0,0]

itertools并不“知道”迭代零是浪费的工作,例如以下迭代将出现在结果中:

List=[0,3,0,0,0,6,0,0,5,0,0]

List=[0,3,0,0,0,6,0,0,5,0,0]

它们是相同的,但是itertools只取第一个零(例如)并将其移动到列表中的第四个位置,反之亦然.

问题是:我怎样才能只迭代一些选定的数字而单独留下其他如零?它可以带或不带itertools.

最佳答案
Voilá – 它现在有效 – 在获得“肉”的排列后,我进一步获得了所有可能的“0”位置和收益率的组合
每个排列的每个可能的“0位置”集合的一个排列
非0的:

from itertools import permutations, combinations

def permut_with_pivot(sequence, pivot=0):
    pivot_indexes = set()
    seq_len = 0
    def yield_non_pivots():
        nonlocal seq_len
        for i, item in enumerate(sequence):
            if item != pivot:
                yield item
            else:
                pivot_indexes.add(i)
        seq_len = i + 1

    def fill_pivots(permutation):
        for pivot_positions in combinations(range(seq_len), len(pivot_indexes)):
            sequence = iter(permutation)
            yield tuple ((pivot if i in pivot_positions else next(sequence)) for i in range(seq_len))

    for permutation in permutations(yield_non_pivots()):
        for filled_permutation in fill_pivots(permutation):
            yield filled_permutation

(我使用了Python的3个“非本地”关键字 – 如果你还在使用Python 2.7,
你将不得不采取另一种方法,比如让seq_len成为一个带有单个项目的列表,然后你可以在内部函数上重新进行处理)

我的第二次尝试(工作实际上是第3次尝试)

这是一种天真的方法,它只是保留已经“看到”的排列的缓存 – 它节省了对每个排列所做的工作,但是没有工作来生成所有可能的排列:

from itertools import permutations

def non_repeating_permutations(seq):
    seen = set()
    for permutation in permutations(seq):
        hperm = hash(permutation)
        if hperm in seen:
            continue
        seen.add(hperm)
        yield permutation

转载注明原文:如何在不“移动”零的情况下生成列表的排列.在Python中 - 代码日志