简体   繁体   English

从给定列表生成大小为 n 的排列,其中每个排列必须包含所有原始值,可能重复

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

I was trying to create a small script that will take the list of elements and create all the possible permutations of its contents, while all those permutations may have repetitions and have to be of size n and contain all the original values.我试图创建一个小脚本,它将获取元素列表并创建其内容的所有可能排列,而所有这些排列可能有重复并且必须是大小为 n 并包含所有原始值。 I tried to use the itertools library but they don't have anything of use.我尝试使用itertools库,但它们没有任何用处。 Is there something simple I can do to achieve that?我可以做一些简单的事情来实现这一目标吗?

Here is an example for the list [0,1,2] and n=3 :这是列表[0,1,2]n=3的示例:

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

For n=4 , something like [0,1,1,2] will also be allowed in the output.对于n=4 ,output 中也将允许类似[0,1,1,2]的内容。

The behavior you described can be implemented with the following function:您描述的行为可以使用以下 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)

Alternatively, if you need this to work over any sequence , instead of just for lists, you could use或者,如果您需要它来处理任何序列,而不仅仅是列表,您可以使用

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)

Both functions behave as follows.这两个函数的行为如下。 Note that for n less than or equal to the length of the input sequence, the functions behave exactly like itertools.permutations .请注意,对于小于或等于输入序列长度的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)]

There is itertools.combinations_with_replacement() .itertools.combinations_with_replacement() [ New in 3.1 ] [ 3.1 中的新功能]

If the sequence length n is equal to number of unique elements, as in your example, then trivially there can be no repetitions, so this would reduce to itertools.permutations()如果序列长度 n 等于唯一元素的数量,如您的示例所示,那么通常不会有重复,因此这将减少到itertools.permutations()

Else for the general case, use a list comprehension to filter the raw output from itertools.combinations_with_replacement() :否则,对于一般情况,使用列表推导过滤来自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.

相关问题 生成具有重复元素的列表排列 - Generate permutations of list with repeated elements 数组的所有排列,其中数组中的每个元素必须按 0 和 n 之间的范围增加 - All permutations of array where each element in the array must be increasing by range between 0 and n 如何有效地从大小为n的列表中获取大小{n,n-1,n-2,... 1}的所有排列? - How to get all permutations of sizes {n, n-1,n-2, … 1} from list of size n efficiently? 从 n+1 生成所有 k 排列而不重新计算 n python 3 中的 k 排列 - generate all k-Permutations from n+1 without recalculate the k-permutations from n python 3 给定每个数字或索引的选择列表,是否有生成可能排列的函数? - Is there a function to generate possible permutations given list of choices for each digit or index? 生成列表的所有排列和该列表中可能列表的排列? - Generate all permutations of a list and permutations of the possible lists within that list? 具有重复元素的排列列表 - List of permutations with repeated elements 为每个索引生成具有单独限制的所有排列 - Generate all permutations with separate limits for each index 在没有递归python的情况下生成最大值为n-1的n by n列表的所有排列 - Generate all permutations of n by n list with max value n-1 without recursion python 如何生成扁平列表列表的所有排列? - How to generate all permutations of the flattened list of lists?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM