迭代器和生成器的一些注意问题
来源:互联网 发布:p2p是什么软件 编辑:程序博客网 时间:2024/06/13 22:06
一、迭代器
可迭代的(可迭代对象):
可迭代对象都是可迭代的。如:str、list、dict、tuple、文件对象等等
只要是对象有__iter__
内部方法,就可以称之为可迭代对象
迭代器:
迭代器也是可迭代的,他不光有__iter__
方法,还有__next__
方法。
迭代器一次只能取一个值,直到取完后引发一个错误
获得一个迭代器:
调用可迭代对象的__iter__()
就可以获得迭代器
使用迭代器:
- 调用迭代器的
__next__()
方法 - 使用for循环
迭代器的特点:
- 惰性运算
- 从前到后一次去取值,过程不可逆 不可重复
- 节省内存
如何判断一个变量是不是迭代器或者可迭代的方法一:print('__iter__' in dir([1,2,3,4]))print('__next__' in dir([1,2,3,4]))方法二:from collections import Iterablefrom collections import Iteratorprint(isinstance([1,2,3,4],Iterable))str_iter = 'abc'.__iter__()print(isinstance(str_iter,Iterator))print(isinstance('abc',Iterable))
二、生成器
生成器的本质就是迭代器,它有迭代器的所有特点,只不过生成器是自己编写的python 代码
1、生成器函数
生成器函数和普通函数之间的区别:
- 生成器函数中含有yield关键字
- 生成器函数调用的时候不会立即执行,而是返回一个生成器
def g_func(): print('aaaa') yield 1 print('bbbb') yield 2 yield 3g = g_func()for i in g: print(i)print(g.__next__())print(g.__next__())print(g.__next__())
def cloth(): for i in range(1000000): yield '衣服%s'%ig = cloth()for i in range(50): print(g.__next__())for i in range(50): print(g.__next__())
2、sned用法(进阶)
def func(): print('*'*10) a = yield 5 print('a : ',a) yield 10g = func()num = g.__next__()# print(num)num2 = g.send('alex')num2 = g.send('aaaa')print(num2)
**在下面的例子中,send会在”yield average”处返回average,并将10传递到”yield average”处
**
def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/countg_avg = averager()g_avg.__next__() ---》 先使用一次生成器,返回的值是Noneprint(g_avg.send(10)) ---》 传递的值是10,然后执行term =10,执行到第二次循环的yield average时候,返回average,这里打印的是第一次循环中的average = total/count计算出的值print(g_avg.send(30)) ---》 从term = 处执行代码,然后把下一次循环的average返回,然后暂停print(g_avg.send(20))print(g_avg.send(100))print(g_avg.send(200))
生成器的预激装饰器
在使用send的时候,需要先使用一次next方法,具体因素参照上面的例子
def init(func): #生成器的预激装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) #func = averager g.__next__() return g return inner@initdef averager(): total = 0.0 count = 0 average = None term = yield average total += term count += 1 average = total/count yield averageg_avg = averager()print(g_avg.send(10))print(g_avg.send(30))
3、总结
- 生成器函数:生成一个生成器的函数
- 生成器的本质参数迭代器
- 生成器函数的特点:
- 带有yield关键字
- 且调用之后,函数内的代码不执行
- 触发执行的方式:
- next
- send :
send(None) == __next__()
,send在next的基础上传一个值到生成器函数内部(send操作不能用在生成器使用的第一次) - for循环
三、生成器表达式
1、引子
(1)、列表推导式
例一:30以内所有能被3整除的数
>>> [i for i in range(30) if i%3 == 0][0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
例二:30以内所有能被3整除的数的平方
>>> [i**2 for i in range(30) if i%3 == 0][0, 9, 36, 81, 144, 225, 324, 441, 576, 729]
例三:找到嵌套列表中名字含有两个‘e’的所有名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]>>> [j for i in names for j in i if j.count('e') == 2]['Jefferson', 'Wesley', 'Steven', 'Jennifer']
(2)、字典推导式
例一:将一个字典的key和value对调
>>> dic = {'a': 10, 'b': 34}>>> {dic[k]:k for k in dic}{10: 'a', 34: 'b'}>>>
例二:合并大小写对应的value值,将k统一成小写
>>> dic= {'a': 10, 'b': 34, 'A': 7, 'Z': 3}>>> {k.lower():dic.get(k.lower(),0) + dic.get(k.upper(),0)for k in dic}{'a': 17, 'b': 34, 'z': 3}
(3)、集合推导式
例:计算列表中每个值的平方,自带去重功能
>>> {i**2 for i in [1,-1,2]}{1, 4}
2、生成器表达式
g = (i*i for i in y)for i in g: print(i)
阅读全文
0 0
- 迭代器和生成器的一些注意问题
- iOS 推送的一些示例代码和注意的问题
- Oracle数据库和JSP连接要注意的一些问题
- Oracle数据库和JSP连接要注意的一些问题
- iOS:苹果推送----一些示例代码和注意的问题
- JSP中一些需要注意和经常忘记的问题
- JavaScript一些需要注意的问题和技巧
- 安装Windows和Linux双系统需要注意的一些问题
- Toolbar和Actionbar需要注意的一些问题
- 一些编程注意的问题
- Servlet的一些注意问题
- 一些应该注意的问题
- 使用“动软代码生成器”需要注意的问题
- 注意Hibernate4在开发当中的一些改变和遇到的一些问题及其解决方案
- Python的迭代器和生成器
- Python的迭代器和生成器
- Python的迭代器和生成器
- python3的迭代器和生成器
- Android移动开发-下拉刷新SwipeRefreshLayout的实现
- 欢迎使用CSDN-markdown编辑器
- JavaScript中数组Array的方法总结
- jsp之间获取参数
- android 无限轮播图
- 迭代器和生成器的一些注意问题
- mui初级入门教程(一)— 小白入手mui的学习路线
- Map集合
- 什么是restful
- Vue.js 上传文件(后台使用.net)
- Java
- iOS百度地图根据经纬度获取两点之间的距离
- ofbiz修复bug——使用内容组件创建博客文章时报错
- Solr6.4.1配置文件详情