Python – 递归和生成器

递归

自己调用自己,但是要分解它的参数

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就变成生成?,而不是函数了;

中括号换成小括号即可

 Python – 递归和生成器

相关推荐