在python中生成排列

时间:2018-08-27 08:08:38

标签: python

我想实现一个函数generate_perm(m,n),该函数带有两个参数,一个是数字以排列(m),第二个是排列之和必须等于(n)。< / p>

def generate_perm(m,n):
    '''
     implement this
    '''
    return

generate_perm(2,5)应该输出

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

generate_perm(3,5)应该输出:

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

编辑 我还没走

def generate_permutations(m, n):
    all = []
    cur = [0 for i in range(m)]
    len_perm = m*2
    while True:
        for i in range(m):
            if cur[i] == 0: # initial case
                if i != m-1:
                    cur[i] = 1
                else:
                    cur[i] = n-m

        all.append(cur)
        if len(all) >= len_perm:
            break
    return all

2 个答案:

答案 0 :(得分:2)

考虑列表l = [1,2,3,4,5]

您可以使用itertools.permutations

获得所有排列
p = itertools.permutations(list(range(1,6)),2)

然后对其进行过滤

my_elems = [el for el in p if sum(el) == 5]

输出

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

看看您提供的第二个示例,我想您想要的是product,而不是permutations

p = itertools.product(list(range(1,6)),repeat=3)

my_elems = [el for el in p if sum(el) == 5]

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

,并且在第一种情况下也适用。

答案 1 :(得分:1)

一种不带任何库的简单递归方法:

def perm(m, n):
  if m == 1:  # base case
    return [(n,)]
  perms = []
  for s in range(1, n):  # combine possible start values: 1 through n-1 ...
    for p in perm(m-1, n-s):  # ... with all appropriate smaller perms 
      perms.append((s,) + p)
  return perms

>>> perm(1, 5)
[(5,)]
>>> perm(2, 5)
[(1, 4), (2, 3), (3, 2), (4, 1)]
>>> perm(3, 5)
[(1, 1, 3), (1, 2, 2), (1, 3, 1), (2, 1, 2), (2, 2, 1), (3, 1, 1)]