迭代器、生成器

一、迭代器

# 双下方法:带双下划线叫双下方法
print([1].__add__([2]))
print([1]+[2])

[1, 2]
[1, 2]

dir():用来展示xx拥有的所有使用方法

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

# 判断是否可迭代
print("__iter__" in dir(int))   # False
print("__iter__" in dir(bool))  # False
print("__iter__" in dir(list))  # True
print("__iter__" in dir(dict))  # True
print("__iter__" in dir(set))   # True
print("__iter__" in dir(tuple))         # True
print("__iter__" in dir(enumerate([]))) # True
print("__iter__" in dir(range(2)))      # True

一个列表执行了__iter__()之后的返回值就是一个迭代器:

print([].__iter__())
# <list_iterator object at 0x000000000109B390>

示例:

lis = [1, 2]
l = lis.__iter__()   # 把列表转换成迭代器
print(l.__next__())  # 通过__next__方法就可以从迭代器中一个一个地取值
print(l.__next__())
print(l.__next__())  # 报错

可迭代:只要含有__iter__方法都是可迭代的

迭代器:同时含有__next__和__iter__方法就是迭代器

判断xx是否可迭代 或 是否是迭代器:

from collections import Iterable
from collections import Iterator

print(isinstance([], Iterable))  # True  可迭代
print(isinstance([], Iterator))  # False 不是迭代器

总结:

  1. 得到一个迭代器格式:可迭代.__iter__()
  2. 迭代器中的__next__()方法可以一个一个的获取值
  3. 只有是可迭代对象的时候,才能用for循环
  4. 当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代(内部是否有__iter__方法)

迭代器的好处:

  1. 从容器类型中一个一个的取值,可以把所有的值都取到
  2. 节省内存空间,迭代器并不会在内存中占用一大块内存,而是随着循环,每次取一点,当然也可以__next__()获取一个值

二、生成器(本质还是迭代器)

# 生成器函数
def func():
    yield "123"

ret = func()
print(ret)  # <generator object func at 0x00000000007C1EB8>
print(ret.__next__())  # 123

注意:

  • 只要含有yield关键字的函数都是生成器函数
  • yield不能和return共用,且需要写在函数内
# yield把返回值返回来,每次__next__()取一个值,并且下一个__next__()会接着取下一个值
# next(xx)等价于xx.__next__()
def func():
    for i in range(1, 4):
        yield "傻逼{}号".format(i)

ret = func()
print(next(ret))  # 傻逼1号
print(next(ret))  # 傻逼2号
print(next(ret))  # 傻逼3号
print(next(ret))  # 报错,没得取了

生成器实现监听文件输入:

def monitor(filename):
    f = open(filename, encoding="utf-8")
    while True:
        for line in f:
            if line.strip():
                yield line.strip()

ret = monitor("1.txt")
for i in ret:
    if "pd" in i:
        print(i)
原文地址:https://www.cnblogs.com/believepd/p/9575878.html