Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为每个索引生成具有单独限制的所有排列_Python_List_Generator_Permutation - Fatal编程技术网

Python 为每个索引生成具有单独限制的所有排列

Python 为每个索引生成具有单独限制的所有排列,python,list,generator,permutation,Python,List,Generator,Permutation,假设我们有一个列表,例如,[3,2,1]。我想以以下形式生成该列表的所有排列: [1, 1, 1], [2, 1, 1], [3, 1, 1], [1, 2, 1], [2, 2, 1] , [3, 2, 1] 对于长度n的任何列表。这样,原始列表的ith元素的值就是所有排列的ith元素的值的上限 我还想使用一个使用yield的生成器,因为输入列表可能相当大(例如,n=30) 到目前为止,我一直在使用这样的东西: itertools.product(range(1, 5), repeat=5)

假设我们有一个列表,例如,
[3,2,1]
。我想以以下形式生成该列表的所有排列:

[1, 1, 1], [2, 1, 1], [3, 1, 1], [1, 2, 1], [2, 2, 1] , [3, 2, 1]
对于长度
n
的任何列表。这样,原始列表的
i
th元素的值就是所有排列的
i
th元素的值的上限

我还想使用一个使用
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]
是有效的输入。

您正在寻找一组范围的笛卡尔乘积,其参数由输入列表定义:

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)]

您可以过滤
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)]
来自itertools导入产品的
>>
>>>l=[3,2,1]

>>>list(filter)(lambda t:all(x此递归函数按所需顺序返回生成器:

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


为什么
[3,3,3]
不是一种可能性?@RafaelC因为第二个元素是2,所有排列的第二个元素必须小于或等于2。我编辑了这个问题来澄清这一点。顺序重要吗?is
[(1,1,1),(1,2,1),(2,2,1),(3,2,1)]
一个有效的解决方案?@FranciscoCouzo问题中的输出顺序更可取,因为它们是其他地方使用的指数,我希望最大的值首先出现在列表的左侧。您能说明示例中的
l
是什么吗?@aL_eX抱歉..更新这真的很低效,它会产生很多对于刚刚被丢弃的元组,我认为对于一般情况,
repeat=3
应该替换为
repeat=len(l)
。@aL_eX.谢谢。更新
>>> print(list(f([3, 2, 1])))
[(1, 1, 1), (2, 1, 1), (3, 1, 1), (1, 2, 1), (2, 2, 1), (3, 2, 1)]