列表元素的全部排列html
case:有乱序、不定长列表如[1,3,5,2],打印全部列表元素全部排列状况,并计数app
思路:重复的步骤--》长度为n的排列-》长为n-1的排列,长为n-2的排列函数
.........spa
直到长度为1,只有一个元素,输入当前的排列顺序code
n = [1,2,3,4] res = [] count = 0 def func1(k,start,end): global count if end == start: count += 1 print(k) # res.append(k[:]) return for i in range(start,end+1): #循环列表,从列表中选取一个元素做为排列的首元素,将剩余n-1的序列传入子递归函数 k[start],k[i] = k[i],k[start] func1(k,start+1,end) k[start],k[i] = k[i],k[start] # 将替换后的序列重置为原来的序列,确保后续循环中,选出的首元素是没选择过的元素
# 递归层数从上往下(由外到内)的过程当中对列表进行新的排列,
# 由内到外的过程当中将列表重置为每层递归函数传入列表的时的排序方式
func1(n,0,len(n)-1) print(count)
升级:将全部排列结果放在一个大列表中htm
n = [1,2,3,4] res = [] count = 0 def func1(k,start,end): global count if end == start: count += 1 print(k) res.append(k[:]) return for i in range(start,end+1): k[start],k[i] = k[i],k[start] func1(k,start+1,end) k[start],k[i] = k[i],k[start] func1(n,0,len(n)-1) print(count)
解释:为何res.append(k[:])而不是res.append(k)?对象
全部递归层数中操做的同一个对象(对象的不一样引用),blog
res.append(k)之后,最终的列表中子元素列表k都指向同一个对象排序
第一句k[start],k[i] = k[i],k[start] 对列表k从新排序以后递归
第二句k[start],k[i] = k[i],k[start] 将列表重置为原来的排序方式,最终结果res大列表中,全部子元素列表都指向同一个对象(新排序而后又重置为原来排序方式的列表)
因此要用切片(浅copy)copy出值相同对象(值相等,可是是两个列表对象)
深浅copy(对象与引用)请参照个人另外一篇文章