day 13
迭代器
python中一切皆对象(数据类型)
总结
Python内置str、list、tuple、dict、set、file
内置有 iter 方法的都叫可迭代的对象
可迭代对象
含有.iter 方法的数据类型就叫做可迭代对象
可迭代的对象执行.iter 方法得到的返回值。并且可迭代对象会有一个 next 方法。
dic = {'a': 1,'b':2,'c'=3}
iter_dic = dic.__iter__()
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
# print(iter_dic.__next__()) # StopIteration
总结
执行可迭代对象的 iter 方法、拿到的返回值就是迭代器对象。
特点
1.内置 next 方法,执行该方法会拿到迭代器对象中的一个值
2.内置有 iter 方法,执行该方法会拿到迭代器本身
3.文件本身就是迭代器对象
缺点
1,取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
2.无法使用len()方法获取长度
for循环原理
for循环称为迭代器循环,in后必须是可迭代的对象
lis = [1,2,3]
for i in lis:
print(i) # 1 2 3
因为迭代器使用__iter__ 后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。
由于对可迭代对象使用 iter 方法后变成一个迭代器对象,这个迭代器对象只是占用一小块内存空间,只有使用__next__ 后才会吐出一个一个值
lis = [1,2,3,4,5...] 相当一个一个鸡蛋,而 lis = [1,2,3,4,5...],iter 相当一只老母鸡,如果你需要蛋,只需要 next 即可
print(range(10)) # range(0,10)
三元表达式
条件成立时的返回值 if 条件 else 条件不成立时的返回值
x = 10
y = 20
if x > y:
print(x)
else:
print(y)
# 三元表达式
print(x) if x > y else print(y)
列表推导式
lt = []
for i in range(10):
lt.append(i)
lt = [i**2 for i in range(10)]
# lt = [i**2(可以做运算) for i in [1,2,3]]
print(lt)
from typing import Iterable # 导出一个可迭代类型
print(isinstance(range(10),Iterbale)) # 判断是否属于该数据类型
字典生成式
print({i:i**2 for i in range(10)})
{0:0,1:1,2:4,3:9,4:16,5:25,6:36,7:49,8:64,9:81}
zip方法
res = zip([1,2,3],[7,7,45,3,2,85]) # res是一个迭代器,__next__返回元组
print(res.__next__()) # type:tuple
print(res.__next__()) # type:tuple
print(res.__next__()) # type:tuple
自此,以上三种表达式仅供了解,装装逼就行,不推荐使用
生成器
yield关键字
在函数中出现yield关键字,在调用函数,就不会继续执行函数体代码,而是会返回一个值
def func():
print(1)
yield
print(2)
yield
g = func()
print(g)
# <generator object func at 0x10ddb6b48>
生成器的本质就是迭代器
yield的特性
1.暂停函数
2.通过next取值
return的特性
1.终止函数
2.通过调用函数拿到值
递归
函数a内部直接调用函数a本身
import sys
sys.setrecursionlimit(10)
print(sys.setrecursionlimit)
def a():
x = 1
print(x)
a()
a()
真正的递归必须得要有退出条件
count = 0
def a():
global count
count += 1
print(count)
if count == 5:
return
a()
a()
递归
1.函数内部调用函数自己
2.必须要有退出条件
3.递归必须要有规律