函数之迭代器、生成器

一、迭代器   (iterator)

1、for循环:对象--->(str  list    tuple   dict   set    文件句柄   range)

Python中的for循环执行机制:

for循环执行的是一个可迭代对象(iterable),

1、内部含有--

l = [1,2,3,4]
for i in l:
    print(i)
1
2
3
4

  我们用while循环来实现一个for循环的功能:

l = [1,2,3]
l_iter = l.__iter__()
while 1:
    try:
        print(l_iter.__next__())
    except StopIteration:
        break
1
2
3

  总结一下:for循环的执行机制:

1、iter的方法,他将可迭代对象转化为迭代器

2、再调用—next 方法

3、他有异常处理的方法

 

2、迭代器认知

什么是可迭代对象:遵循可迭代协议

  PS  :可迭代协议:

可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法

 

如何判断是否是可迭代对象?

方法一、dir(被测试对象)输出结果中含有—iter—则他是可迭代对象

a = 'abc'
print(dir(a))-----a 的所有用法
print('__iter__'in dir(a))
 
#Ture

  方法二、isinstance  判定

from collections import Iterable
from collections import Iterator
l = [1,2,3,4]
print(isinstance(l,Iterable))
print(isinstance(l,Iterator))

Ture
False

  

可迭代对象与迭代器之间的转换:iterable  ----->  iterator

可迭代对象.__iter__()  ---> #迭代器
# a = 'alex'
# b = a.__iter__()

  

迭代器取值:

s1 = 'abcd'
s2 = s1.__iter__()
print(s2.__next__())
print(s2.__next__())
print(s2.__next__())
print(s2.__next__())
a
b
c
d
#  迭代器.__next__()  

  

迭代器与可迭代对象的区别:

s1 = 'abcd'
s2 = s1.__iter__()
print('__iter__'in dir(s1))        #Ture
print('__iter__'in dir(s2))        #Ture
print('__next__'in dir(s1))      #False
print('__next__'in dir(s2))      #Ture

 ** 只含有__iter__方法的数据是可迭代对象,含有__iter__方法并含有__next__方法的数据是迭代器。

 

迭代器的意义:

1、迭代器节省内存

2、迭代器有惰性机制

3、迭代器不能反复,需要一直执行下去

 

PS:range()-----是可迭代对象,不是迭代器

print('__next__' in dir(range(10)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__
print('__iter__' in dir(range(10)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__

from collections import Iterator
print(isinstance(range(100000000),Iterator))  #验证range执行之后得到的结果不是一个迭代器

  

 

二、生成器   (generator)

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

# 1,可以用生成器函数
# 2,可以用各种推导式构建迭代器.
# 3,可以通过数据转化.

生成器函数
def gener():
    print('aaa')
    yield 222
    print('bbb')
    yield 333
    print('ccc')
g = gener()
print(g)              #  <generator object gener at 0x0000000002864A98>  生成器对象
print(g.__next__())   #  aaa
                         222

print(g.__next__())   # bbb
                      # 333

  return yield 区别

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

yiled 返回给调用者值,并将指针停留着当前位置.

 

     send 用法 

1,send 和next功能一样
2, 给上一个yiled 整体发送一个值
send不能给最后一个yield发送值
获取第一个值的时候,不能用send 只能用next
def gener():
    yield 222
    count = yield 333
    print('-------->',count)
    yield 'aaa'
    yield 'bbb'
g = gener()

print(g.__next__())
print(g.__next__())

print(g.send('AAAA'))

print(g.__next__())

输出:

222
333
--------> AAAA
aaa
bbb

 

posted @ 2018-02-06 16:23  GuoXY  阅读(144)  评论(0编辑  收藏  举报