簡體   English   中英

為每個索引生成具有單獨限制的所有排列

[英]Generate all permutations with separate limits for each index

假設我們有一個列表,例如[3, 2, 1] 我想以以下形式生成該列表的所有排列:

[1, 1, 1], [2, 1, 1], [3, 1, 1], [1, 2, 1], [2, 2, 1] , [3, 2, 1]

對於任何長度為n列表。 這樣一來,價值i原單個元素的值的上限, i日所有排列的元素。

我還想使用使用yield的生成器,因為輸入列表可能非常大(例如n = 30 )。

到目前為止,我一直在使用這樣的東西:

itertools.product(range(1, 5), repeat=5)

for循環中使用時具有以下輸出:

(1, 1, 1, 1, 1), (1, 1, 1, 1, 2), (1, 1, 1, 1, 3), (1, 1, 1, 1, 4), (1, 1, 1, 2, 1), (1, 1, 1, 2, 2), (1, 1, 1, 2, 3), ... 

但是,我認為它不允許為排列的每個元素指定自定義限制。

另外,請注意,輸入列表的元素不一定必須是連續數字,因此[25, 17, 10, 4]是有效輸入。

您可以過濾itertools.product的結果

>>> from itertools import product
>>> l = [3,2,1]
>>> list(filter(lambda t: all(x<=y for x,y in zip(t,l)), product(l, repeat=len(l))))
[(3, 2, 1), (3, 1, 1), (2, 2, 1), (2, 1, 1), (1, 2, 1), (1, 1, 1)]

此遞歸函數按所需順序返回生成器:

def f(limits):
    if not limits:
        yield ()
        return

    for l in f(limits[1:]):
        for i in range(1, limits[0]+1):
            yield (i,) + l

>>> print(list(f([3, 2, 1])))
[(1, 1, 1), (2, 1, 1), (3, 1, 1), (1, 2, 1), (2, 2, 1), (3, 2, 1)]

您正在尋找一系列范圍的笛卡爾積,其參數由您的輸入列表定義:

from itertools import product
lims = [3, 2, 1]
gen = product(*(range(1,lim+1) for lim in lims))
print(list(gen))

結果是

[(1, 1, 1), (1, 2, 1), (2, 1, 1), (2, 2, 1), (3, 1, 1), (3, 2, 1)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM