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

时间:2016-06-09 13:32:19

标签: python list permutation

使用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

3 个答案:

答案 0 :(得分:3)

Voilá - 它现在有效 - 在获得“肉”的排列后,我进一步得到所有可能的“0”位置和收益率的组合 每个排列的每个可能的“0个位置”的一个排列 非0s:

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

答案 1 :(得分:0)

将每个结果附加到List。现在,您将拥有所有可能的组合,然后执行以下操作:

list(set(your_big_list))

Set会将列表缩小到仅限于唯一排列。 我不完全确定这是你要解决的问题,还是你担心性能问题。 无论刚刚创建了一个帐户,我想我会尝试贡献一些东西

答案 2 :(得分:0)

您的问题不清楚,但如果您尝试在输出中没有0的情况下列出排列,则可以按以下方式执行:

from itertools import permutations
def perms( listy ):
    return permutations( [i for i in listy if i!=0])