Python全栈(第一期)Day13

今日主要内容:
迭代器
生成器
监听文件输入

一,迭代器

1,基本理论知识

# 一个列表执行了__iter__()之后的返回值就是一个迭代器
#print(dir([]))
#print(dir([].__iter__()))
print(set(dir([].__iter__())) - set(dir([])))

print([1, 'a', 'bbb'].__iter__().__length_hint__())  #元素个数



输出结果:
{'__setstate__', '__length_hint__', '__next__'}
3

只要是能被for循环的数据类型 就一定拥有__iter__方法

print('__iter__' in dir(int))   #可以判断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)))

输出结果:
False
False
True
True
True
True
True
True

2,理解迭代器

l = [1, 2, 3]
iterator = l.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
#print(iterator.__next__())  #这里会出错,因为元素已经迭代结束

输出结果:
1
2
3

# Iterable  可迭代的    -- > __iter__  #只要含有__iter__方法的都是可迭代的
# [].__iter__() 迭代器  -- > __next__  #通过next就可以从迭代器中一个一个的取值

# 可迭代协议:只要含有__iter__方法的都是可迭代的
# 迭代器协议:内部含有__next__ 和 __iter__ 方法的就是迭代器
# 可迭代  和  迭代器  是两个概念


print('__iter__' in dir([].__iter__()))
print('__next__' in dir([].__iter__()))

输出结果:
True
True

更加简单的判断方法:

from collections import Iterable
from collections import Iterator



print(isinstance([], Iterator))  #判断[]是不是一个迭代器
print(isinstance([].__iter__(), Iterator))  #判断[]是不是一个迭代器
print(isinstance([], Iterable))  #判断[]是不是可迭代的







class A:
    def __iter__(self):
        pass
    def __next__(self):
        pass

a = A()
print(isinstance(a, Iterator))
print(isinstance(a, Iterable))

输出结果:
False
True
True
True
True

概念:

迭代器的概念
迭代器协议 —— 内部含有__next__和__iter__方法的就是迭代器
迭代器协议和可迭代协议:
可以被for循环的都是可迭代的
可迭代的内部都有__iter__方法
只要是迭代器 一定可迭代
可迭代的.iter()方法就可以得到一个迭代器
迭代器中的__next__()方法可以一个一个的获取值

for:
只有 是可迭代对象的时候 才能用for
当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代
当我们使用for循环的时候,内部实际操作如下:
for循环的本质就是迭代器


iterator = l.__iter__()
iterator.__next__()

迭代器的优点:

#迭代器的好处:
    # 从容器类型中一个一个的取值,会把所有的值都取到。
    # 节省内存空间
        #迭代器并不会在内存中再占用一大块内存,
            # 而是随着循环 每次生成一个
            # 每次next每次给我一个

3,迭代器实战

case1:

'''
自己模拟一个迭代器
'''
l = [1, 2, 3, 45]
iterator = l.__iter__()
k = 0
while True:
    k = k + 1
    print(iterator.__next__())
    if k == len(l):
        break

输出结果:
1
2
3
45

case2:

# 我现在想要一个2000000的字符串,但是下面的方法只保存了最后一个!
def func():
    for i in range(2000000):
        i = 'wahaha%s' % i
    return i

ret = func()
print(ret)

'''
迭代器并不能满足我们日常写代码的需求
如果我们平时在写代码的时候 需要用到大量的数据,但是我们不希望他一次性生成
------>生成器
'''

输出结果:
wahaha1999999

二,生成器

’’’
生成器的优点:
需要大量数据的时候,不会同时占据内存。
‘’'

'''
yield - return:
相同点:都可以把后边的值返回
不同点:yield 执行结束之后,并不会结束,但是也没有接着执行。而是可以接着接收

'''

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

ret = generator()
print(ret)          #并没有打印1,说明函数根本没有被执行
print(ret.__next__())
print(ret.__iter__())

输出结果:
<generator object generator at 0x000002D70CE3ED58>
1
a
<generator object generator at 0x000002D70CE3ED58>

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

'''
深度理解for循环
'''
#case1:
ret = g.__next__()
print(ret)
print('0000000000000000')
ret = g.__next__()
print(ret)
print('0000000000000000')
ret = g.__next__()
print(ret)

print('0000000000000000')
#case2:
for i in g:
    print(i)

输出结果:
<generator object generator at 0x0000028D74B1ED58>
1
a
0000000000000000
2
b
0000000000000000
c
0000000000000000
d

解决迭代器case2中的问题:

def wahaha():
    for i in range(2000000):
        yield '娃哈哈%s'% i



g = wahaha()
count = 0
for i in g:
    count += 1
    print(i)
    if count > 5:
        break
print('*******', g.__next__())    # 我们还可以接着走!!!
for i in g:
    count += 1
    print(i)
    if count > 10:
        break

输出结果:
娃哈哈0
娃哈哈1
娃哈哈2
娃哈哈3
娃哈哈4
娃哈哈5
******* 娃哈哈6
娃哈哈7
娃哈哈8
娃哈哈9
娃哈哈10
娃哈哈11

思考一个问题:

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

for i in l:
    print(i)

'''
从生成器回来,思考上面这个问题,为什么不接着输出呢?
答案:两个for循环 会生成两个迭代器!两个是没有关系的
'''

输出结果:
1
2
1
2
3
4

三,实战

'''
用户在输入的同时,我们能通过程序看到用户在输入的东西
'''

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:
    print(i)
    if 'python' in i:
        print('***', i)

猜你喜欢

转载自blog.csdn.net/qq_42615032/article/details/84591248