博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迭代器和生成器
阅读量:6292 次
发布时间:2019-06-22

本文共 2967 字,大约阅读时间需要 9 分钟。

迭代器

iterable

l1=[1,1,1,1,1,1,1,1,1]#列表l2=l1.__iter__()  #迭代器print("__iter__" in dir(l1))#查看是否是可迭代对象的方法print("__iter__" in dir(l2))#上面列表和迭代器这两个都是可以迭代的对象.print("__next__" in dir(l1))#不是迭代器print("__next__" in dir(l2))#是迭代器print(l1.__next__())报错print(l2.__next__())迭代器的三个意义
代码演示

迭代器的意义

因为是逐行循环的所以节省内存,

有惰性机制

迭代器不能反复,从头向下执行,执行到哪里就会是哪里,往后不会从头开始执行

 

try异常处理

try:

要输入的异常错误代码

except:

break

 

生成器

本质其实其迭代器,其实是用代码编写的迭代器

三种方式

1,可以用生成器函数

关键字

yield

yield和return的却别

1.返回调用的值并停留在当前的位置.

def func():    print(11,1,1,1,1,1)    yieldprint(func())#简单的生成器
是其结果
View Code

 

2,可以用各种推导公式

3.可以用数据转换

send和next的用法一样

__send__

给上一个yeild返回一个值,不能用在最后一个和第一个.

生成器的三种方法

1.生成器函数

yield函数可以生成一个生成器

2.各种推导公式

l2=[i for i in rang (111)]

l2=[i for i in range(111) if ]

3.数据转化的生成器

转化为列表元组,

list()tuple()

 

1、迭代器

可迭代对象:它的方法含有__iter__,可被for循环的对象。

for循环 str list tuple dict set 文件句柄

①可迭代对象(iterable)与迭代器(iterator)的关系:

可迭代对象---->迭代器:可迭代对象.__iter__()    迭代器遵循迭代器协议。

迭代器取值:s.__next__()  每次取一个值。

可迭代对象和迭代器区别:只含有__iter__方法的数据是可迭代对象,含有__iter__方法并且含有__next__方法的数据是迭代器。

②可迭代对象判断方法:

方法一:dir(被测试对象),print('__iter__' in dir(s)),如果它的方法含有__iter__,那这个对象就叫做可迭代对象。遵循可迭代协议。

方法二:测试它是迭代器还是可迭代对象。

1
2
3
4
5
6
= 
[
1
,
2
,
3
,
4
]
l_iter 
= 
l.__iter__()
from 
collections 
import 
Iterable  
#可迭代对象
from 
collections 
import 
Iterator   
#迭代器
print
(
isinstance
(l,Iterable))
print
(
isinstance
(l,Iterator))

 

③迭代器的特点。

Ⅰ 节省内存

Ⅱ迭代器惰性机制

Ⅲ迭代器不能反复,一直向下执行。不可逆。

④for循环的内部机制。

for循环的内部含有__iter__方法,它会将可迭代对象先转化成迭代器,然后再调用__next__方法取值,它有异常处理的方法。

⑤可迭代对象:str list tuple dict set 

迭代器:文件句柄

 

2、生成器

生成器的本质就是迭代器,生成器是自己用Python代码写的迭代器。

含有yield就是生成器。

(1)用生成器函数写生成器。

1
2
3
4
5
6
#生成器函数
def 
gener():
    
print
(
111
)
    
yield 
222
= 
gener()
print
(g)

.__next__()遇到yield停住,可以再一次.__next__()来继续执行,如果.__next__()找不到下一个yield就会报错。

send和.__next__功能一样,但是send会给上一个yield整体发送一个值,所以最后一个yield永远得不到send发送的值,获取第一个值的时候不能用send只能用next

注:

return和yield区别:

return返回给调用者值,并结束此函数。

yield返回给调用者值,并将指针停留在当前位置。

(2)推导式/生成器表达式构建迭代器。

①列表推导式

Ⅰ 列表推导式(循环模式):[变量(加工后的数据)for 变量i in 可迭代的数据类型]

l2
= 
[
'python%s期'
%
i
for 
i
in 
range
(
1
,
11
)]
print
(l2)

Ⅱ列表推导式(筛选模式):[变量(加工后的数据)for 变量i in 可迭代的数据类型 if 条件]

l3
= 
[i
for 
i
in 
range
(
31
)
if 
i
%
3 
=
=
0
]   
#30以内能被3整除的数
print
(l3)
#找到嵌套列表中名字含有两个‘e’的所有名字names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]print([name for lst in names for name in lst if name.count('e') >= 2])

列表推导式比较直观,占内存。生成器表达式(for循环)不容易看出内容,但是省内存。

②字典推导式

#将一个字典的key和value对调
mcase
= 
{
'a'
:
10
,
'b'
:
34
}
mcase_frequency
= 
{mcase[k]: k
for 
k
in 
mcase}
print
(mcase_frequency)

 

#合并大小写对应的value值,将k统一成小写
mcase
= 
{
'a'
:
10
,
'b'
:
34
,
'A'
:
7
,
'Z'
:
3
}
mcase_frequency
= 
{k.lower(): mcase.get(k.lower(),
0
)
+ 
mcase.get(k.upper(),
0
)
for 
k
in 
mcase.keys()}
print
(mcase_frequency)

③集合推导式

#计算列表中每个值的平方,自带去重功能
squared
= 
{x
*
*
2 
for 
x
in 
[
1
,
-
1
,
2
]}
print
(squared)
# Output: set([1, 4])

(3)可以通过数据转化

 list()和tuple()将生成器对象转化,一般不需要。

转载于:https://www.cnblogs.com/cangshuchirou/p/8422615.html

你可能感兴趣的文章
PLM产品技术的发展趋势 来源:e-works 作者:清软英泰 党伟升 罗先海 耿坤瑛
查看>>
vue part3.3 小案例ajax (axios) 及页面异步显示
查看>>
浅谈MVC3自定义分页
查看>>
.net中ashx文件有什么用?功能有那些,一般用在什么情况下?
查看>>
select、poll、epoll之间的区别总结[整理]【转】
查看>>
CSS基础知识(上)
查看>>
PHP中常见的面试题2(附答案)
查看>>
26.Azure备份服务器(下)
查看>>
mybatis学习
查看>>
LCD的接口类型详解
查看>>
Spring Boot Unregistering JMX-exposed beans on shutdown
查看>>
poi 导入导出的api说明(大全)
查看>>
Mono for Android 优势与劣势
查看>>
将图片转成base64字符串并在JSP页面显示的Java代码
查看>>
js 面试题
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>
腾讯云下安装 nodejs + 实现 Nginx 反向代理
查看>>
Javascript 中的 Array 操作
查看>>
java中包容易出现的错误及权限问题
查看>>
AngularJS之初级Route【一】(六)
查看>>