IT小白鼠第十二天

迭代器

可迭代对象

内部含有__iter__方法的就是可迭代对象,遵循可迭代协议。

可迭代协议:

假如我们自己写了一个数据类型,希望这个数据类型里的东西也可以使用for被一个一个的取出来,那我们就必须满足for的要求。这个要求就叫做“协议”。

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

dir:查看对象所有方法

# print(dir('123')) # '__iter__'----------------------------True
# print('__iter__' in dir([1, 2, 3]))---------------------------True
# print('__iter__' in dir({'name':'alex'}))---------------------------True
# print('__iter__' in dir({'name'}))---------------------------True
# print('__iter__' in dir((1, 2, 3)))---------------------------True
# print('__iter__' in dir(1)) --------------------------- False
# print('__iter__' in dir(True))--------------------------- False

什么是迭代器?

  可迭代对象通过__iter__()可以转换成迭代器,满足迭代器协议。

  内部含有__iter__且__next__方法的就是迭代器。

# l = [1, 2, 3]
# l_obj = l.__iter__()
# print(l_obj)

迭代器的取值两种方法:

复制代码
l = [1, 2, 3]
l_obj = l.__iter__()
print(l_obj)------------------<list_iterator object at 0x000002B84DE73748>
方法一:__next__()
print(l_obj.__next__())-------------1
print(l_obj.__next__())-------------2
print(l_obj.__next__())-------------3

方法二 for循环
for i in l_obj:
    print(i)
print('__next__' in dir(l_obj))
-------------1
        2
        3
        True
复制代码

第二种判断方法:

from collections import Iterable
from collections import Iterator
print(isinstance('123', Iterable))
print(isinstance('123', Iterator))

迭代器:

  1,节省内存

扫描二维码关注公众号,回复: 3254171 查看本文章

  2,满足惰性机制

  3,取值过程单向不可逆(一条路走到黑)

 

迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

for循环,能遍历一个可迭代对象,他的内部到底进行了什么?

  • 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
  • 内部使用__next__方法,一个一个取值。
  • 加了try异常处理功能,取值到底后自动停止,防止报错。

用while循环模拟for循环:

复制代码
l = [1, 2, 3, 4, 5]
l_obj = l.__iter__()
while True:
    try:
        print(l_obj.__next__())
    except Exception:
        break
------------1
            2
            3
            4
            5
复制代码

生成器

生成器本质也是迭代器,生成器是自己用python构建的迭代器

  1,通过生成器函数构建

  2,通过生成器推导式构建。

复制代码
def func1():
    print(666)
    return 222
ret = func1()
print(ret)----------------666
                                    222

def func1():
    print(11)
    print(333)
    yield 222
    print(666)
    yield 777
g_obj = func1()  # 生成器对象 generator object
print(g_obj.__next__())
print(g_obj.__next__())
--------------------------11
                                    333
                                    222
                                    666
                                    777  
复制代码
复制代码
def cloth1():
    for i in range(1,10001):
        print('衣服%s' % i)
cloth1()  

打印''衣服+序号'’直到----------衣服10000


def cloth2():
    for i in range(1,10001):
        yield '衣服%s' % i

g = cloth2()
for i in range(1,51):
    print(g.__next__())

for i in range(1, 151):
    print(g.__next__())
打印''衣服+序号''   一直打印到----衣服200
复制代码

next --- send

复制代码
def func1():
    count = yield 222
    print(count)
    yield 777
    yield 888
g_obj = func1()  # 生成器对象 generator object
print(g_obj.__next__())
print(g_obj.send('wusir'))
-----------------222
                        wusir
                        777        
复制代码

  1,send具有next功能

  2,send可以给上一个yield传值。

  3,第一个取值不会使用send

  4,最后一个yield不会得到send的值、

列表推导式:

  能用列表推导式完成的,用python代码都可以完成。用一句话构建一个你想要的列表。

  优点:简单,稍微难理解

  缺点:不能用debug

猜你喜欢

转载自www.cnblogs.com/liurenli/p/9669123.html