[英]Python itertools permutations without repetitions
I have a string show the step going in mxn grid like this problem: https://leetcode.com/problems/unique-paths/我有一个字符串显示 mxn 网格中的步骤,就像这个问题: https : //leetcode.com/problems/unique-paths/
step = 'DDRR'
D mean go Down and R mean go to Right I want to show permutations without replacement, and i found the itertools built-in on Python.But it's say: D 表示向下,R 表示向右,我想显示不替换的排列,我发现 Python 内置了 itertools。但它说:
Elements are treated as unique based on their position, not on their value.
元素被视为唯一基于它们的位置,而不是它们的值。 So if the input elements are unique, there will be no repeat values.
所以如果输入元素是唯一的,就不会有重复值。
So that when I using itertools.permutation(step,4), it's contain many replications.所以当我使用 itertools.permutation(step,4) 时,它包含许多复制。
>>> itertools.permutations(step,4)
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'R', 'D', 'R')
('D', 'R', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('R', 'D', 'R', 'D')
('R', 'R', 'D', 'D')
('R', 'R', 'D', 'D')
I want something like:我想要这样的东西:
('R', 'D', 'R', 'D')
('R', 'D', 'D', 'R')
('D', 'R', 'R', 'D')
('D', 'D', 'R', 'R')
('D', 'R', 'D', 'R')
('R', 'R', 'D', 'D')
I found some answer using set(itertools.permutations(step,4)) , but because apply set() method, the itertools.permutation() method still calculate all possibilities.我使用set(itertools.permutations(step,4))找到了一些答案,但是因为应用 set() 方法, itertools.permutation() 方法仍然计算所有可能性。 Is there anyway to avoid it, or is there any built-in function can do permutation without repetitions in Python ?
无论如何要避免它,或者是否有任何内置函数可以在 Python 中不重复地进行排列?
To get the answer you need, you could use multiset_permutations要获得您需要的答案,您可以使用multiset_permutations
>>> from sympy.utilities.iterables import multiset_permutations
>>> from pprint import pprint
>>> pprint(list(multiset_permutations(['D','D','R','R'])))
[['D', 'D', 'R', 'R'],
['D', 'R', 'D', 'R'],
['D', 'R', 'R', 'D'],
['R', 'D', 'D', 'R'],
['R', 'D', 'R', 'D'],
['R', 'R', 'D', 'D']]
To get just the total number, use factorial of number of items divided by the product of factorials for the count of each unique item.要获得总数,请使用项目数的阶乘除以阶乘的乘积来计算每个唯一项目的数量。 Here there are 2 D's and 2 R's
这里有2个D和2个R
>>> from math import factorial
>>> factorial(4)//(factorial(2)*factorial(2))
6
The leetcode problem only asks about the number of unique paths, not a list of unique paths, so to calculate the number you only need to use the combination formula of C(n, k) = n! / (k! x (n - k)!)
leetcode 问题只询问唯一路径的数量,而不是唯一路径的列表,因此计算数量只需要使用
C(n, k) = n! / (k! x (n - k)!)
的组合公式即可C(n, k) = n! / (k! x (n - k)!)
C(n, k) = n! / (k! x (n - k)!)
to find the number of positions where D
s (or R
s) can be placed out of all positions: C(n, k) = n! / (k! x (n - k)!)
找出所有位置中可以放置D
s(或R
s)的位置数:
from math import factorial
def f(m, n):
return factorial(m + n - 2) / factorial(m - 1) / factorial(n - 1)
so that f(3, 2)
returns: 3
所以
f(3, 2)
返回: 3
and that f(7, 3)
returns: 28
并且
f(7, 3)
返回: 28
On the other hand, if you're interested in producing a list of unique paths, you can use itertools.combinations
to do the same as above;另一方面,如果您有兴趣生成唯一路径列表,您可以使用
itertools.combinations
执行与上述相同的操作; that is, to find the positions where D
s (or R
s) can be placed out of all positions:也就是说,要找到可以在所有位置中放置
D
s(或R
s)的位置:
from itertools import combinations
def f(m, n):
for positions in map(set, combinations(range(m + n - 2), m - 1)):
yield ''.join('DR'[i in positions] for i in range(m + n - 2))
so that:以便:
print(*f(7, 3), sep='\n')
outputs:输出:
RRRRRRDD
RRRRRDRD
RRRRRDDR
RRRRDRRD
RRRRDRDR
RRRRDDRR
RRRDRRRD
RRRDRRDR
RRRDRDRR
RRRDDRRR
RRDRRRRD
RRDRRRDR
RRDRRDRR
RRDRDRRR
RRDDRRRR
RDRRRRRD
RDRRRRDR
RDRRRDRR
RDRRDRRR
RDRDRRRR
RDDRRRRR
DRRRRRRD
DRRRRRDR
DRRRRDRR
DRRRDRRR
DRRDRRRR
DRDRRRRR
DDRRRRRR
It's a terribly inefficient solution anyway.无论如何,这是一个非常低效的解决方案。 Just compute the number directly:
直接计算数字:
math.comb(m + n - 2, m - 1)
尝试使用 itertools.combinationss(step,4) 而不是 itertools.permutations(step,4)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.