x青年欢乐多 2020-02-22
自己调用自己,但是要分解它的参数
def fact(n): if n == 0: return 1 else: return n*fact(n-1) print(fact(5)) # 120
1、递归必须包含一个基本出口(base case),否则会无限递归,最终导致栈溢出.比如这里就是n==0返回1
2、递归必须包含一个可以分解的问题(recursive case),想要求得fact(n),就需要用nfact(n-1)
3、递归必须要向着递归出口靠近(toward the base case).这里每次递归调用都会n-1,向着递归出口n==0靠近
def get_sum(num): # 递归完成1+2+3...+10的和 if num>=1: res = num + get_sum(num -1) else: res = 0 return res res = get_sum(12) print(res)
迭代器是一个可以记住遍历的位置对象.
迭代器对象从集合的第一个元素开始访问,直到所有的元素被完全被访问完结束.
迭代器有两个基本方法iter()和next(),其中iter()用来创建迭代器对象.next()用来遍历字符串,列表或元祖对象时经常会用到迭代器.
lst = ["苹果", "香蕉", "橘子", "桃子"] aa = iter(lst) # 创建迭代器对象 print(next(aa)) print(next(aa)) print(next(aa)) # 苹果 # 香蕉 # 橘子 # 迭代器只能往前遍历元素,而不会后退,用for语句遍历 lst = ["奔驰", "宝马", "奥迪", "别克"] bb = iter(lst) for a in bb: print(a, end=" ") # 奔驰 宝马 奥迪 别克
在Python中,使用yield的函数被称为生成器.
与普通函数不同的是,生成器将返回一个迭代器的函数,而且生成器只能用于迭代操作.可见,生成器是一种特殊的迭代器.
在调用生成器的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值.并在下一次执行next()方法时从当前位置继续运行.
list = [[1, 2], [3, 4], [5, 6], [7, 8]] # 创建一个嵌套列表 def qtlb(list): # 创建生成器 for aa in list: for bb in aa: yield bb for nn in qtlb(list): print(nn)
在需要的时候产生结果,节省我们资源,不使用的时候不占内存
每次执行到yield,因为底层的实现就是中断的原理,保存栈帧,加载栈帧.
迭代器:带状态的对象,它会记录当前迭代所在的位置,以便下次迭代的时候获取正确的元素;
生成器:在Python中是一种很常用也很好用的数据结构,比起列表(list)来说,迭代器最大的优势就是延迟计算,按需使用,从而提高开发体验和运行效率,以至于在Python3中map,filter等操作返回的不再是列表而是迭代器.把一个列表生成式的[]中括号改为()小括号,就创建一个生成器:
list = [x*x for x in range(10)] # 列表生成式 print(list) generator_ex = (x*x for x in range(10)) # 生成器 print(generator_ex) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # <generator object <genexpr> at 0x031A0F08>
1、列表表达式的 [] 改为 () 即可变成生成?
2、函数在返回值得时候出现yield就变成生成?,而不是函数了;
中括号换成小括号即可