递归函数:一个会调用自身的函数【在一个函数的内部,自己调用自己】
递归调用
递归中包含了一种隐式的循环,他会重复指定某段代码【函数体】,但这种循环不需要条件控制
使用递归解决问题思路:
a.找到一个临界条件【临界值】
b.找到相邻两次循环之间的关系
c.一般情况下,会找到一个规律【公式】
代码演示:
# 函数自己调用自己就是递归
# 需求:通过递归的方式,封装一个函数,计算 n! (n是传入的数字)
# 5! ===> 5*4*3*2*1==>5 * 4!
# 4! ===> 4*3*2*1 ===>4 * 3!
# 3! ===> 3*2*1====> 3 * 2!
# 2! ===> 2*1 ===> 2 * 1!
# 1! ===> 1
#总结如下:
# n! = n * (n-1)!
'''
a.找到一个临界值(临界条件) 1! = 1
b.找到两个循环之间的关系
c.总结规律: n! = n * (n-1)!
'''
defdigui(n):
ifn==1:
return1
returnn*digui(n-1)
print(digui(6))
# 通过递归封装一个函数,传入一个数字m,得到第m个斐波那契数列
# 1 1 2 3 5 8 13 21 34 55 89
deffn(m):
ifm<3:
return1
returnfn(m-1) +fn(m-2)
print(fn(8))
注意:以后在实际项目中尽量少用递归,如果隐式循环的次数太多,会导致内存泄漏【栈溢出】 python默认的递归次数限制为1000次左右.以免耗尽计算机的内存.
优点:简化代码,逻辑清晰
list comprehension
系统内置的用于创建list的方式
range(start,end,step)缺点:生成的列表一般情况下都是等差数列
代码演示:
# 最基本的列表
# 1.生成1-10之间所有的数字
list1=list(range(1,11))
print(list1)
# 需求:通过程序的方式生成列表 [1,4,9,16,25]
#第一种方法:使用原始的方式生成
list2= []
foriinrange(1,6):
list2.append(i**2)
print(list2)
# 第二种方法:使用列表生成式
list3= [i**2foriinrange(1,6)]
print(list3) # [1, 4, 9, 16, 25]
# 使用列表生成式 生成1-10之间所有的奇数
list4= [iforiinrange(1,11) ifi%2==1]
print(list4)
# 使用列表生成式 生成1-10之间所有的奇数并且能被3整除的数字
list5= [iforiinrange(1,11) ifi%2==1andi%3==0]
print(list5)
# 列表生成式中使用双重循环
list6= [i+jforiin"xyz"forjin"987"]
print(list6)
# 字典生成式:(了解)
dict1= {i:i*iforiinrange(1,6)}
print(dict1)
# 集合生成式:(了解)
set1= {i*iforiinrange(1,6)}
print(set1)
generator
next()
代码演示:
# 定义生成器: 只需要把列表生成式的[] 换成() 即可
g= (i**2foriinrange(1,10))
print(g)
print(type(g)) #<class 'generator'>
# 生成器得到的数据不能直接输出,要想访问里面的数据,必须使用next() 进行遍历,每调用一次next() 就会输出一个数据
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
# 当通过next() 将生成器中的数据遍历完毕以后,接着调用next(),就会出现StopIteration
# print(next(g)) # StopIteration
# 生成器的应用场景:
'''
当需要生成无穷多的数据时,一般使用生成器. 若使用列表生成无穷多的数,会占用大量的空间,不合适.
'''
# 生成器相关的函数 yield
'''
1.yield存在于函数中,当普通函数中有了yield关键词,该普通函数变为了生成器函数.
2.调用生成器函数不会执行代码,需要使用next
3.可以在函数的内部不断地返回值,但是不会终止函数的执行(与return不同)
4.每次调用next以后,程序会在yield处暂停
'''
deftest(m):
print("m=",m)
yieldm*2
print("m+1=",m+1)
yield (m+1) *2
print("m+2",m+2)
g=test(23) # 在普通函数test中加入了关键字yield,那该函数变成了生成器函数,直接调用不会执行.
print(type(g)) # <class 'generator'>
print(next(g)) # 函数执行到第一个yiled处暂停
print(next(g)) # 函数执行到第二个yiled处暂停