p67-p71

迭代器

  • 迭代对象:内部含有iter方法的对象 int str list set 句柄大部分都是 bool不是
  • 迭代器:内部含有iter 方法和 next 方法的对象 只有句柄f是
  • 迭代器特点:节省内存,迭代器在内存中只占用一个数据的空间,每次取值,上一条数据空间会释放掉
l1 = [1,2,3,4] #只是迭代对象
print('__iter__' in dir(l1)) #return True
print('__next__' in dir(l1)) #return False

obj = l1.__iter__() #转化迭代器
print('__iter__' in dir(obj)) #return True
print('__next__' in dir(obj)) #return True
  • 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
l1 = [1,2,3,4]
print('__iter__' in dir(l1)) #return True
print('__next__' in dir(l1)) #return False
obj = l1.__iter__() #转化迭代器
print('__iter__' in dir(obj)) #return True
print('__next__' in dir(obj)) #return True
a = obj.__next__() #利用next进行取值 
print(a) #return 1
a = obj.__next__()
print(a) #return 2
a = obj.__next__()
print(a) #return 3
a = obj.__next__()
print(a) #return 4
a = obj.__next__()
print(a) #return StopIteration
  • for循环的循环对象一定要是可迭代对象,但并不意味着可迭代对象就可以取值,for循环的内部机制是,将可迭代对象转化成迭代器,然后利用next 取值,最后利用异常处理抛出异常
l1 = [1,2,3,4,5,6]
obj = l1.__iter__() # 将可迭代对象转化成迭代器
while 1: #利用while循环 next取值
    try:
        print(next(obj))
    except StopIteration: #利用异常处理,终止循环
        break
l1 = [1,2,3,4,5,6,]
obj = iter(l1)
for i in range(2):
    print(next(obj)) #return 1,2 每次取一个值
for i in range(2):
    print(next(obj)) #return 3,4
with open('test3.txt',encoding='utf-8',mode='w') as f1:
    print('__iter__' in dir(f1))
    print('__next__' in dir(f1)) #return True 文件句柄是迭代器
l1 = [11,22,33,44,55]
obj = iter(l1) #转化成迭代器
print(next(obj)) #用next取值
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj)) #已经取完,报错 StopIteration

可迭代对象和迭代器的对比

  • 可迭代对象:是一个方法比较多,操作灵活,比较直观,但是占用内存,而且不能通过迭代取值的数据集
  • 迭代器:非常节省内存,可以记录取值位置,可以通过next方法取值,但不直观,操作单一,如果数据量大,可以选择迭代器

生成器

  • 本质是迭代器
  • 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是需要我们自己用python代码构建的工具。最大的区别也就如此了。
  • 三种创建方式:
  • 1、通过生成器函数
#1
def func():
    print(11) #return 11
    return 22
ret = func()
print(ret) #return 22
#2
def func():
    print(11) 
    yield 22  #yield 关键字
ret = func()
print(ret) #return <generator object func at 0x037AB3E0>
#
def func():
    print(11)
    yield 22
ret = func()
print(ret.__next__()) #return 11,22
  • 第二个函数中有yield 关键字,那么这个函数 func 就是生成器函数,直接加括号并不是执行函数,而是获取一个生成器对象,然而生成器对象是通过next方法取值

yeild 和 return的区别

  • return:一般在函数中只设置一个,用于终止函数,并返回值

  • yield :在生成器函数中可以设置多个,并不终止函数,

列表推导式

#10以内的整数的平方写入列表
l1 = [i**2 for i in range(1,11)]
print(l1) #return [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#100以内的所有的偶数写入列表
l1 = [i for i in range(1,101) if i%2==0]
print(l1)
#从python1期 到 python100期 写入列表中
l1 = ['python'+str(i)+'期' for i in range(1,101)]
print(l1)

#或者
l1 = [f'python{i}期' for i in range(1,101)]
print(l1)
#names = [['Su','Lee','Herry'],['Lucy','Jerry','Tom']] 名字中含有2个r的筛选到一个新列表
names = [['Su','Lee','Herry'],['Lucy','Jerry','Tom']]
l1 = [name for i in names for name in i if name.count('r')==2]
print(l1) #return ['Herry', 'Jerry']

生成器表达式

  • 与列表推导式几乎一样,也有筛选模式,循环模式,多层循环构建,写法上需要把[]换成()
print([i for i in range(1,11)]) #return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print((i for i in range(1,11))) #return <generator object <genexpr> at 0x02EFB3E0> 变成生成器
  • 列表推导式只能构建比较复杂并且有规律的列表
  • 超过三层的循环才能成功的,就不建议用列表推导式
  • 查找错误不行,不容易发现,debug模式难排错
  • 但是简单,一行搞定
  • 装逼
#字典推导式
l1=['Jay','Coco','Cindy']
l2=['周杰伦','李玟','王心凌']
dic = {l1[i]:l2[i] for i in range(len(l1))}
print(dic) #return {'Jay': '周杰伦', 'Coco': '李玟', 'Cindy': '王心凌'}

内置函数

  • python 提供了 63个内置函数 len print input
posted on 2020-07-08 19:33  94小渣渣  阅读(99)  评论(0编辑  收藏  举报