Python全栈学习笔记day 13:迭代器、生成器

一、迭代器

字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的。

print(dir([]))                                                    #告诉我列表拥有的所有方法
ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10)))
print(ret)                                                        #iterable
print('__iter__' in dir(int))
print('__iter__' in dir(bool))
print('__iter__' in dir(list))
print('__iter__' in dir(dict))
print('__iter__' in dir(set))
print('__iter__' in dir(tuple))
print('__iter__' in dir(enumerate([])))
print('__iter__' in dir(range(1)))


#输出:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
{'__str__', '__hash__', '__subclasshook__', '__ge__', '__len__', '__reduce_ex__', '__ne__', '__new__', '__getitem__', '__doc__', '__repr__', '__le__', '__reduce__', '__class__', '__delattr__', '__iter__', '__contains__', '__dir__', '__init__', '__eq__', '__init_subclass__', '__format__', '__getattribute__', '__gt__', '__sizeof__', '__lt__', '__setattr__'}
False
False
True
True
True
True
True
True

由以上可以得知:

只要是能被for循环的数据类型 就一定拥有 __iter__ 方法
print([].__iter__())



#输出
<list_iterator object at 0x00C2AE30>
一个列表执行了__iter__()之后的返回值就是一个迭代器
print(dir([]))
print(dir([].__iter__()))
print(set(dir([].__iter__())) - set(dir([])))    
链表迭代器方法的集合 - 链表方法的集合 =链表迭代器有的方法而链表没有的

输出:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
{'__next__', '__length_hint__', '__setstate__'}

重点学习:{'__next__', '__length_hint__'}

print([1,'a','bbb'].__iter__().__length_hint__()) 


输出:3


.__length_hint__() 返回元素个数
l = [1,2,3]
iterator = l.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())



输出:
1
2
3
StopIteration    :报错的意思,原因是链表中只有3个元素,第四次迭代时已经没元素了,所以报错

总结:

Iterable  可迭代的    -- > __iter__ 只要含有__iter__方法的都是可迭代的
[].__iter__() 迭代器  -- > __next__ 通过next就可以从迭代器中一个一个的取值
只要含有__iter__方法的都是可迭代的 —— 可迭代协议
迭代器协议 : 内部含有__next__和__iter__方法的就是迭代器
可以被for循环的都是可迭代的
# 可迭代的内部都有__iter__方法
# 只要是迭代器 一定可迭代
# 可迭代的.__iter__()方法就可以得到一个迭代器
# 迭代器中的__next__()方法可以一个一个的获取值
for
只有 是可迭代对象的时候 才能用for
当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代
迭代器的好处:
    # 从容器类型中一个一个的取值,会把所有的值都取到。
    # 节省内存空间
        #迭代器并不会在内存中再占用一大块内存,
            # 而是随着循环 每次生成一个
            # 每次next每次给我一个

二、生成器

1、只要含有yield关键字的函数都是生成器函数     yield不能和return共用且需要写在函数内
def generator():
    print(1)
    yield 'a'
#生成器函数 : 执行之后会得到一个生成器作为返回值
ret = generator()
print(ret)
print(ret.__next__())


输出:
<generator object generator at 0x00914DF0>
1
a

2、yield会结束本次迭代。并且在一个迭代器中迭代时,下一次迭代是挨着上一次迭代的位置迭代的

     栗子:

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'

g = generator()
ret = g.__next__()
print(ret)

输出:
1
a

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()

ret = g.__next__()
print(ret)
ret = g.__next__()
print(ret)

输出:
1
a
2
b
def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()

ret = g.__next__()
print(ret)
ret = g.__next__()
print(ret)
ret = g.__next__()
print(ret)

输出:
1
a
2
b
c

三、监听文件输入的例子

def tail(filename):
    f = open(filename,encoding='utf-8')
    while True:
        line = f.readline()
        if line.strip():
            yield line.strip()

g = tail('file')
for i in g:
    if 'python' in i:
        print('***',i)

猜你喜欢

转载自blog.csdn.net/qq_35883464/article/details/82992645
今日推荐