递归
在函数内部可以调用其他函数;
可以调用自己【递归】
递归:自己调用自己
在计算机中,函数调用是通过栈(stack)这种数据结构实现的,
每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。
由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
斐波那契数列:
# 1、1、2、3、5、8、13、21、34、……
# n是下标,求第几位的值是多少
def factorial(n):
if n<1:
return -1
elif n==1 or n==2:
return 1
else:
return factorial(n-1)+factorial(n-2)
result=factorial(10)
print(result)
# 求阶层
fact(n)=n!=1×2×3×⋅⋅⋅×(n−1)×n=(n−1)!×n=fact(n−1)×n
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
迭代
能用for…in的就叫迭代。🤬🤡
判断是否可迭代🙄
from collections import Iterable
print(isinstance('abc',Iterable)) # True
print(isinstance([1,2,3],Iterable)) # True
print(isinstance((1,2,3),Iterable)) # True
print(isinstance(123,Iterable)) # False
print(isinstance({1:'a',2:'b'},Iterable)) # True
可见:
字符串,列表,元组,字典可迭代
数字不可迭代
字典
dict = {'a':1,'b':2,'c':2}
# 打印key:
for k in dict:
print(k) # a b c
# 打印value:
for v in dict.values():
print(v) # 1,2,2
# 打印key和value:
for k,v in dict.items():
print(k,v)
'''
a 1
b 2
c 2
'''
列表
list1 = ['a','b','c','d','e','f']
for item in list1:
print(item) #a b c d e f
# 列表的索引和值
for index,value in enumerate(list1):
print(index,value)
'''
0 a
1 b
2 c
3 d
4 e
5 f
'''
列表生成式
python 内置的生成列表的
最简单的
print(list(range(1,11))) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
'''
语法:
根据x计算的表达式 for 条件
写列表生成式时,把要生成的元素x放到前面,前面的部分是一个表达式,它必须根据x计算出一个结果,后面跟for循环,就可以把list创建出来;
for循环后面还可以加上if判断,例如筛选出偶数的平方。
'''
# 使用循环太麻烦,列表生成式简化代码
ls1 = [x for x in range(16)]
print(ls1) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
ls2 = [x*x for x in range(16)]
print(ls2) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225]
ls3 = [x*x for x in range(16) if x%2==0]
print(ls3) # [0, 4, 16, 36, 64, 100, 144, 196]
# 前面是根据x生成的表达式
ls4 = [x if x%2==0 else -x for x in range(11)]
print(ls4) # [0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
x的表达式【前面】 for列表 条件【后面】;
【后面】只有if没有else,加了else会报错,因为是一个筛选条件,加了else是两个;
【前面】有if有else,缺一不可,因为前面需要一个条件表达式;
生成器
目的:
利用列表生成器生成一个有一百万个元素的列表,内存占用量大;如果仅仅使用前几个元素,
后面元素占用的空间就白白浪费了。🙄浪费是可耻的
🙄浪费真可耻
生成器就是解决这个【没用到元素占用空间的问题的呢】
🤩生成器的创建方式【一】:
列表生成式的[] 改成 ()。
😚号外号外,中括号改成圆括号就是生成器啦
r1 = [x*x if x>0 else -x for x in range(-5,11) if x%2==1]
print(r1) # [5, 3, 1, 1, 9, 25, 49, 81]
r2 = (x*x if x>0 else -x for x in range(-5,11) if x%2 ==1)
print(r2) # <generator object <genexpr> at 0x0000019553844410>
🤡生成器可用next(),for调用,生成器是可迭代的:
print(next(r2)) # 5,next()获取一次,借助while,当生成器中没有元素时再调用next(),程序会报StopIteration的错🤢,推荐使用for,不会报错的啦。
for r in r2:
print(r)
'''
5
3
1
1
9
25
49
81
'''
🥗yield生成器🥗
生成器中保存的是算法,
当列表生成器无法满足其逻辑时,可以用函数来实现生成器,
例如斐波那契数列
1,1,2,3,5,8...
# 递归版斐波那契数列,index是下标,第几位的值是多少
def fd(index):
if index < 1:
return -1
if index == 1 or index ==2:
return 1
else:
return fd(index-1)+fd(index-2)
print(fd(6)) # 8
# 普通版斐波那契数列
def f(max):
n,a,b = 0,0,1
while n<max:
print(b)
a,b = b,a+b
n=n+1
return 'done'
f(6) # 1 1 2 3 5 8
# 生成器版斐波那契数列
def fs(max):
n,a,b = 0,0,1
while n<max:
yield b
a,b = b,a+b
n = n+1
return 'done'
r = fs(6)
print(r) # <generator object fs at 0x00000177959A4A98>
赋值语句a,b = b,a+b的原理:
🀄元组,取值,赋值🀄
tu = (b, a + b) # t是一个tuple
a = tu[0]
b = tu[1]