可迭代对象:obj.__iter__
迭代器:iter1=obj.__iter()
1iter1.__next__
2iter2.__next__
迭代器:
优点:不依赖索引
惰性计算,节省内存
缺点:
不如按照索引的取值方便
一次性,只能往后取,不能回退
迭代器的应用:
- 提供了一种不依赖索引的统一的迭代方法
- 惰性计算,比如取文件的每一行
判断可是否是可迭代对象和迭代器
from collections import Iterable, Iterator # 导入模块功能
isinstance(a, Iterable) 查看a是否为可迭代对象
isinstance(a, Iterator) 查看a是否为可迭代器
迭代器:
d={‘a‘:1,‘c‘:2,‘b‘:3} obj=d.__iter__() while 1: #while 迭代 try: i=obj.__next__() print(i) except StopIteration: break for i in d: #for 迭代 print(i)
字符串,列表元组,字典,集合,文件都是可迭代的,只有文件是迭代器
生成器:
生成器函数:函数体内包含有yield关键字,该函数的执行结果是生成器函数
生成器函数运行的得到生成器
生成器就是迭代器
yield的功能:
- 与return 类似,都可以返回值,但不一样的地方在于yeild返回多次值,而return只能返回一次值
- 为函数封装好了__iter__ 和__next__,把函数的执行结果做成一个迭代器
- 遵循迭代器的取值方式obj.__next(),触发的函数执行,函数暂停与再继续的状态都是由yiel保存
(包含yield的函数)
yield 可以进行返回值操作,如果后面没有yield拦住,作为返回值,会报错 StopIteration
def foo():
print(111)
yield 1 # 如果打印下面.__next__的结果的话,会打印这个返回值
print(222)
f = foo() # 运行这一句的时候,系统不会运行 foo(),而是直接生成一个迭代器f
f.__next__()
f.__next__()
def producer(): print(‘first------>‘) yield 1 print(‘second------>‘) yield 2 print(‘third------->‘) yield 3 for i in producer(): print(i)
def countdown(n): print(‘start countdown‘) while n>0: yield n n-=1 print(‘stop countdown‘) for i in countdown(9): print(i)
列表解析
# 要求:将 s = ‘hello‘ 放到新列表中
[i.upper() for i in s] # for 循环得到i,将i作为列表的元素
# 要求:判断列表 l = [1,31,73,84,57]中的元素, 如果大于30,就将i加入新列表
res = [i for i in l if i > 30]
加入字典的值(i) 循环( for i in l ) 条件( if i > 30 )
三元表达式
res = 2 if 2 > 3 else 3 # 正确时执行 判断条件 错误时执行
print(res)
结果:3 # 执行结果为 3
学习实例:
import time def tail_func(filename,encoding=‘utf-8‘): with open(filename,‘r‘,encoding=encoding) as f: f.seek(0,2) while 1: line=f.readline() if line: yield line else: time.sleep(0.5) def grep_func(lines,pattern): for line in lines: if pattern in line: print( line) b=tail_func(‘b.txt‘) c=grep_func(b,‘error‘) for i in grep_func(c,‘404‘): print(i)
编写 tail -f a.txt |grep ‘error‘ |grep ‘404‘命令