一,迭代器
1,迭代器的概念:
重复的过程称为迭代,每次重复即一次迭代,并且每一次迭代都是下一次的初始值
2,为什么要有迭代器:
字典,集合都没有下标
但也取出的需求我们能有不依赖下标的索方式就是迭代器
迭代器可以迭代的对象python解释器内置的方法
3,如何看是不是可以迭代的:
凡是有_init_都是可以迭代的对象,凡是能够_next_都是迭代器
4,为什么要用迭代器:
优点:
迭代器提供了一种不依赖索引的取值方式,这样就可以遍历那些没有索引的迭代对象(字典,集合,文件)
迭代器和列表相比较,迭代器是惰性计算,更节省空间
缺点:
永远无法获取迭代器的长度使用不入列表索引取值灵活
一次只能往后取值,不能倒着取值
5,迭代器的基本例子:
d={'a':1,'b':2,'c':3} #可迭代的:只要对象本身有__iter__方法,那它就是可迭代的 d={'a':1,'b':2,'c':3} d.__iter__ = #iter(d) #执行对象下的__iter__方法,得到的结果就是迭代器 i=d.__iter__() #: 这个返回值i就叫迭代器就相当于你执行iter就做成迭代器 print(i.__next__()) #:这个位置next一个都是无序的,next一个就取一个值 print(i.__next__()) print(i.__next__()) #:这个如果太多也会报错的 # print(i.__next__())
6,异常扑捉:
# d={'a':1,'b':2,'c':3} # i=iter(d) # while True: # try: #:异常辅捉 try except # print(next(i)) #:前3次不会出现异常第四次出现异常就退出 # except StopIteration: # break
7,查看可迭代和迭代对象:
#查看可迭代与迭代器对象 # from collections import Iterable,Iterator # s='hello' # l=[1,2,3] # t=(1,2,3) # d={'a':1} # set1={1,2,3,4} # f=open('a.txt') #都是可迭代的 # s.__iter__() # l.__iter__() # t.__iter__() # d.__iter__() # set1.__iter__() # f.__iter__() # print(isinstance(s,Iterable)) # print(isinstance(l,Iterable)) # print(isinstance(t,Iterable)) # print(isinstance(d,Iterable)) # print(isinstance(set1,Iterable)) # print(isinstance(f,Iterable)) #查看是否是迭代器 # print(isinstance(s,Iterator)) # print(isinstance(l,Iterator)) # print(isinstance(t,Iterator)) # print(isinstance(d,Iterator)) # print(isinstance(set1,Iterator)) # print(isinstance(f,Iterator))
二,生成器
1,生成器yield与returen的区别?:
return只能返回一次函数就彻底结束了,但是yield能返回多个值
2,yield到底干了什么事情:
yield吧函数变成了生成器 ————》就是迭代器的一部分
函数的暂停以及继续都是由yield保存的
3,生成器的功能用途:
模拟管道 惰性计算
4,什么是yield表达式:
变量名=yield
4,什么是生成器:
生成器就是一个函数,这个函数包含yield关键字
例子:
def e(name): print('%s吃东西 '%name) food_list = [] while True: food=yield food_list #:send(“大鸡块”)先传给yield然后yield在传值给food然后打印 print('%s吃%s食物'%(name,food)) #:循环过来遇到yield返回到food_list food_list.append(food) print(done) c=e('小刚') print(next(c)) #:或者g.send(none)初始化操作 print(c.send("鸡公煲")) print(c.send("大鸡块")) print(c.send("咖喱鸡"))
如果不想每次都要调print(next(c))
def timmer(func):
def wrapper(*args,**kwargs):
g=func(*args,**kwargs)
return
return wrapper
调@timmer
5,e.send()与next(e)的区别:
(1),如果函数内yield的是表达式的形式(yield=food),那必须先next(e)
(2), 二者的共同地方在于都能让函数上一次暂停的位置继续运行
(3)不一样在于send触发函数的下一次代码的执行时会顺带把下一个值传下去
八,三元表达式,列表解析,生成器表达式
1,三元表达式:
# 书写格式 result = 值1 if 条件 else 值2 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量 #:例子:res = True if 1>2 else False
2,列表解析:就是生一窝鸡蛋(优点:方便改变了编程习惯,声明式编程)
food_list=[] for i in range(10): food_list.append('鸡蛋%s'%i) print(food_list)
egg_list=['鸡蛋%s'%i for i in range(10)]
#:例子:
res=[i for i in range(10) i>5]
3,生成器表达式:一筐鸡蛋变成了一只鸡,想要的时候就下一个蛋具有生成器的特点
egg_list=[] for i in range(10): egg_list.append('鸡蛋%s'%i) chincken=('鸡蛋%s'%i for i in range(10)) print(chincken) print(next(chincken))
#:例子:res=(i for i in range(10) i> 5)
生成器表达式的优点地方:省内存,一次只产生一个值在内存中
应用:读取一个大的文件的所有内容并且处理行
f=open('a.txt') g=(line.strip() for line in f) print(next(g)) #:一行一行取值 print(next(g)) print(next(g))
列表表达式和函数表达式的语法区别[]------------>()
作业:
1,编写函数tail - f a.txt |grep 'error' |grep '404' (就是忘文件里写信息当遇到设置的信息就会打印出来)
import time def tail(filepath,encoding='utf-8'): with open(filepath,encoding=encoding) as f: f.seek(0,2) #:文件很大移动到最后一行 while True: line=f.readline() if line: # print(line) #:如果有新的内容就读 yield line else: time.sleep(0.5) #:如果没有睡几秒在读 def grep(lines,pattern): for line in lines: if pattern in line: print(line) g=tail('a.txt') g2=grep(g,'error') g3=grep(g2,'404') for i in g3: print(i),
2,文件 a.txt 内容
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3
1,求花了多少钱
f=open('a.txt') g=(line.split() for line in f) sum(float(price)*float(count) for _,price,count in g)
2,
要求使用列表解析,从文件a.txt中取出每一行,做成下述格
[{‘name’:'apple','price':10,'count':3},{...},{...},...]
f=open("a.txt") f.seek(1) #:移动光标 li=[line.strip() for line in f] print(li)
3,与格式2一样,单是保留大于1000的商品信息
# with open('b.txt') as f: # res=(line.split() for line in f) # dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res if float(i[1]) > 10000) # print(list(dic_g)