python递归排序组合_如何用Python求list的排列组合:一种递归方式

问题描述:

给定一个包含n个元素的列表,从中选择m个元素作为一个子列表,求解所有可能的子列表。

例如:

一个列表是[1,2,3,4],从中任选3个数作为一个子列表。

则所有可能的子列表为:[1,2,3], [1,2,4], [1,3,4], [2,3,4]。共有

种。

用python语言描述就是:

def getSubLists(lis=[],m=0):

allAns=[]

# type your code here

return allAns

| 输入: [1,2,3,4]

| 输出:[[1,2,3], [1,2,4], [1,3,4], [2,3,4]]

问题分析:

从数学角度来看,从n个数字中任取m个,所有可能的取法总数量为:

。用Python求这个数量结果是很简单的,但是要实际输出所有组合时,却不是易事(对我自己而言)。

就我自己的经验而言,例如从[a,b,c,d,e]中任选3个,我一般会采用如下搜索方式手动去找出所有组合:

这种方法反映了一种递归思想:

选定了原列表种第

个数作为子列表第一个数,接下来就是把原列表第

数作为子列表第二个数,最后从原列表第

个数后面的所有数中任选一个作为子列表第三个数。

也就是说,一旦确定了“谁”作为子列表第一个数,那么接下来采用的方法都是一样的,这不就是递归嘛!

编程实现:

若要采用递归方式,那问题描述中的函数getSubLists不能直接调用自己,因为每次自我调用后,存储结果的allAns会被刷新,所以可以定义辅助函数subLists专门用来做递归:

def getSubLists(lis=[],m=0):

allAns = [] #用来存储所有递归中的子列表

ans = [None for i in range(m)] #预先填充m个None,用来存储每次递归中的子列表

subLists(lis,m,ans,allAns)

return allAns

def subLists(lis=[],m=0,ans=[],allAns=[]):

# recursive function codes

if m==0:

# m==0是某次递归返回的条件之一:子列表的第三个数已经选出。

# 意味着已到达某个方向的最大递归深度

print('allAns is ',allAns,'before append ans:',ans)

allAns.append(ans.copy())

#这里有意思了,如果不用copy,那么ans即使已经存储在allAns,也会被其它递归方向中的ans刷新

print('allAns is ', allAns, 'after append ans:', ans)

return

if len(lis)

# 递归函数直接返回的条件之一:从4个数里面选5个数出来是不可能的。

print("short list!")

return

length=len(lis)

for iter in range(length-m+1): #可以作为子列表一员的数在lis中的index

ans[-m]=lis[iter] #lis[iter]作为子列表倒数第m个数

if iter+1

subLists(lis[iter+1:],m-1,ans,allAns)

else:

print('allAns is ', allAns, 'before append ans:', ans)

allAns.append(ans.copy())

print('allAns is ', allAns, 'after append ans:', ans)

return

好了,是不是挺简单的,来试一下效果:

if __name__=='__main__':

liss=[1,2,3,4]

m=3

print('The answer for choosing any 3 Numbers from the list:',getSubLists(liss,m))

Outputs:

allAns is [] before append ans: [1, 2, 3]

allAns is [[1, 2, 3]] after append ans: [1, 2, 3]

allAns is [[1, 2, 3]] before append ans: [1, 2, 4]

allAns is [[1, 2, 3], [1, 2, 4]] after append ans: [1, 2, 4]

allAns is [[1, 2, 3], [1, 2, 4]] before append ans: [1, 3, 4]

allAns is [[1, 2, 3], [1, 2, 4], [1, 3, 4]] after append ans: [1, 3, 4]

allAns is [[1, 2, 3], [1, 2, 4], [1, 3, 4]] before append ans: [2, 3, 4]

allAns is [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] after append ans: [2, 3, 4]

The answer for choosing any 3 Numbers from the list: [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

Bingo! 欢迎指教

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值