迭代器

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)
    yield
print(func())#简单的生成器
<generator object func at 0x0000020C2D1D8780>是其结果
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()将生成器对象转化,一般不需要。

posted on 2018-02-07 16:02  仓鼠大人爱吃肉  阅读(409)  评论(0编辑  收藏  举报