第13天-迭代器和生成器
2018-09-29 03:59:08来源:博客园 阅读 ()
迭代器
迭代就是重复的一个过程,但是不是单纯的重复,每一次的重复都是基于上一次的结果产生的。不过只记住迭代他就是重复的执行过程就是了。
#单纯的重复不是迭代,例如: count = 0 while count < 3: print(count) count += 1 #每一次的重复都是基于上一次的结果产生的,随着count的改变输出不同的结果 count = 0 list = ["a", "b", "c"] while count < 3: print(list[count]) count += 1
迭代器就是迭代取数的一个工具,关键是我们为什么要用迭代器呢?我们都知道python中主要的一些数据类型有整型,字符串,元祖,列表,字典,集合,文件等。对于整型而言只要一个数没有什么迭代器的概念,对于字符串,元祖和列表我们可以通过索引去取值,但是对于字典,集合以及文件而言,我们怎么去像列表一样进行取值呢?这就是迭代器引入的原因,主要就是为了不依赖与索引进行迭代取值。在python中两个概念,一个就是可迭代对象(只要有__iter__方法的我们就称之为可迭代对象,字符串,元祖,列表,字典,集合都是可迭代对象),二是迭代器对象(不仅要有__iter__方法而且还要有__next__方法,文件是迭代器对象),从上面的描述我们就可以看出来,迭代器对象都是可迭代的对象,但是可迭代对象却不一定是迭代器对象。
迭代器的使用方法
dic = {'name': 'hu', 'age': 12} iter_dic = dic.__iter__() # 可迭代对象要变成迭代器才能够进行使用 res = iter_dic.__next__() # 变成迭代器之后通过__next__方法进行迭代取值 print(res) # 对于dic迭代的值是key
当迭代器把迭代对象循环完毕之后会报错
dic = {'name': 'hu', 'age': 12} count = 0 iter_dic = dic.__iter__() # 可迭代对象要变成迭代器才能够进行使用 while count < len(dic): try: # 当最后一个迭代完了之后会报错,因此我们需要捕捉异常 res = iter_dic.__next__() # 变成迭代器之后通过__next__方法进行迭代取值 print(res) # 对于dic迭代的值是key except StopIteration: break
从上面的代码我们就可以看出来,对于迭代器的使用太过于麻烦,因此python给我们专门的设计了一个循环for循环来解决这样的事情,for循环可以专门的去解决可迭代对象的问题,当然迭代器对象的问题也可以,for循环处理的步骤1. 把可迭代对象转换成迭代器,(迭代器的话也会执行__iter__的方法,效果是一样的)2. 循环的去调用__next__方法进行迭代取值。3. 通过try去捕捉异常,捕捉到异常之后停止循环。
# 和上面的代码显示的效果是一样的 dic = {'name': 'hu', 'age': 12} for i in dic: print(i)
生成器
生成器本质上就是迭代器,只不过这个生成器是我们自己通过yield关键字自己创建的迭代器而已。迭代器有两个优点 1. 可以不依赖与索引迭代取值 2.节省内存。而我们创建生成器为了解决最大的问题其实就是节省内存。
生成器创建的规则, 通过yield关键字进行创建迭代器。yield和return返回的是一样的,只是yield可以中断函数,当我需要的时候可以重新再进行创建
def foo() print(1) yield "第一" print(2) yield "第二" iter_foo = foo() print(iter_foo) next(iter_foo)
三元表达式
def max2(a, b): if a > b: return a else: return b a = 1 b = 2 c = a if a > b else b # 这一行数据就是上面那一个函数的简洁的表达方式 print(c) c = max2(a, b) print(c)
列表生成式
l = [] for i in range(10): if i > 5: s = "egg%s" % i l.append(s) print(l) l = ["egg%s" % i for i in range(10) if i > 5] # 这一句话和前面的几句话都是性质是一样的,只是简写了而已 print(l)
生成字典表达式
d = {} s = [("hu", 12), ("zhou", 14)] for k, v in s: d[k] = v print(d) d = {k : v for k, v in s} # 这个是上面几行代码的缩写 print(d)
生成器表达式
res = (i ** 2 for i in range(5)) print(res) print(next(res)) print(next(res)) print(next(res))
练习题:
1. 编写一个range的生成器
def my_range(start, end , step=1): while start < end: yield start start += step for i in my_range(0, 10): print(i)
2. 求一个文件中所包含的字符的个数,以及左右行中最大的个数
with open(r'04_多层装饰器的联系.py', 'rt', encoding='utf-8') as f: # count = 0 # for line in f: # count += 1 # data = f.read() # print(len(data)) 649 # count = 0 # for line in f: # count += len(line) # print(count) # print(sum(len(line) for line in f)) print(max(len(line) for line in f)) # 通过生成器表达式一行写出
3. 模拟管道,实现功能:tail -f access.log | grep '404'
# 2、模拟管道,实现功能:tail -f access.log | grep '404' import time def tail(file_path): with open(file_path, 'rb') as f: f.seek(0, 2) while True: # 查看是否有新的一行加入 line = f.readline() if line: yield line else: time.sleep(0.2) def grep(pattern, iter_tail): for line in iter_tail: line = line.decode('utf-8') if pattern in line: yield line for line in grep('404', tail('access.log')): print(line)
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:循环结构for
- Python学习日记(十) 生成器和迭代器 2019-08-13
- python学习-39 生成器总结 2019-07-24
- python学习-38迭代器和生成器 2019-07-24
- Python-11-生成器 2019-07-24
- Python-10-迭代器 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash