簡體   English   中英

從給定列表生成大小為 n 的排列,其中每個排列必須包含所有原始值,可能重復

[英]Generate permutations of size n from given list, where each permutations must contain all of the original values, possibly repeated

我試圖創建一個小腳本,它將獲取元素列表並創建其內容的所有可能排列,而所有這些排列可能有重復並且必須是大小為 n 並包含所有原始值。 我嘗試使用itertools庫,但它們沒有任何用處。 我可以做一些簡單的事情來實現這一目標嗎?

這是列表[0,1,2]n=3的示例:

[0,1,2]
[0,2,1]
[1,0,2]
[2,0,1]
[1,2,0]
[2,1,0]

對於n=4 ,output 中也將允許類似[0,1,1,2]的內容。

您描述的行為可以使用以下 function 來實現:

def perms_with_duplicates(lst: list, n: int) -> Iterator:
    """
    Generate permutations of ``lst`` with length ``n``. 
    If ``n`` is greater than the length of ``lst``, then the
    resulting permutations will include duplicate elements 
    from ``lst``. All of the original elements of ``lst``
    are guaranteed to appear in each output permutation.
    """
    
    # Number of duplicate entries that the permutations can include.
    num_dupl = max(n - len(lst) + 1, 1)
    
    return itertools.permutations(lst * num_dupl, n)

或者,如果您需要它來處理任何序列,而不僅僅是列表,您可以使用

def perms_with_duplicates(seq: Sequence, n: int) -> Iterator:
    """
    Generate permutations of ``seq`` with length ``n``. 
    If ``n`` is greater than the length of `seq`, then the
    resulting permutations will include duplicate elements 
    from ``seq``. All of the original elements of ``seq``
    are guaranteed to appear in each output permutation.
    """
    
    # Number of duplicate entries that the permutations can include.
    num_dupl = max(n - len(seq) + 1, 1)

    it_dupl =  itertools.chain.from_iterable(
        itertools.repeat(seq, num_dupl)
    )
    
    return itertools.permutations(it_dupl, n)

這兩個函數的行為如下。 請注意,對於小於或等於輸入序列長度的n ,函數的行為與itertools.permutations完全相同。

>>> l = [0, 1, 2]

>>> list(perms_with_duplicates(l, 3))                                                                                                
[(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]

>>> len(list(perms_with_duplicates(l, 4)))
360

>>> list(perms_with_duplicates(l, 4))                                                                                                
[(0, 1, 2, 0),
 (0, 1, 2, 1),
 (0, 1, 2, 2),
 (0, 1, 0, 2),
 (0, 1, 0, 1),
 ...
 (1, 2, 1, 0),
 (1, 2, 1, 0),
 (1, 2, 1, 2),
 (1, 2, 0, 0),
 (1, 2, 0, 1),
 ...
 (2, 1, 0, 2)]

itertools.combinations_with_replacement() [ 3.1 中的新功能]

如果序列長度 n 等於唯一元素的數量,如您的示例所示,那么通常不會有重復,因此這將減少到itertools.permutations()

否則,對於一般情況,使用列表推導過濾來自itertools.combinations_with_replacement()的原始 output :

from itertools import combinations_with_replacement

elems = [0,1,1,2]

[comb for comb in combinations_with_replacement(elems, 4) if all(el in comb for el in elems)]

[(0, 0, 1, 2), (0, 0, 1, 2), (0, 1, 1, 2), (0, 1, 1, 2), (0, 1, 2, 2), (0, 1, 1, 2), (0, 1, 2, 2)]

暫無
暫無

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

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