Python的迭代器与生成器

88 阅读3分钟

迭代器

迭代器是什么

在python中,例如str,list,tuple,dict,set,open都是可迭代的数据类型,可迭代的数据类型都会提供一个叫做迭代器(iterable)的东西。这个迭代器可以帮助我们逐一的拿到数据。

迭代器的基本形式

for 变量  in 可迭代:
    pass

获取迭代器的两种方案

  1. 内置函数iter()直接拿到迭代器,()中传入内容
it = iter("你叫什么名字啊")
print(it) # <str_iterator object at 0x10cec7040>

iter中可以传入需要迭代的内容。上面代码中的it就是一个迭代器了,我们可以用for循环对其进行遍历。

for value in it:
    print(value,end='\t'); # 你	叫	什	么	名	字	啊

使用next从迭代器中拿到内容。

it = iter("你叫什么名字啊")
print(it) # <str_iterator object at 0x1004ba040>

print(next(it)) #你
print(next(it)) #叫
print(next(it)) #什
print(next(it)) #么
print(next(it)) #名
print(next(it)) #字
print(next(it)) #啊
#print(next(it)) # StopIteration :迭代已经停止了,不可以再次从迭代器中拿东西了

2.__ iter__()特殊方法 使用方式

it = "呵呵哒".__iter__()

使用__next__()拿到

it = "呵呵哒".__iter__()
print(it)
print(it.__next__())
print(it.__next__())
print(it.__next__())

模拟for循环的工作原理

# 模拟for循环的工作原理
s = "我是数据"
it = s.__iter__()

while 1:
    try:
        data = it.__next__()
        print(data)
    except StopIteration:
        break
s = "你好啊,我叫赛利亚"
it = s.__iter__()

for mm in it:
    print(mm)

几个注意事项以及总结

'''
for 变量  in 可迭代:
    pass

iterable:可迭代的东西
str,list,tuple,dict,set,open
可迭代的数据类型都会提供一个叫迭代器的东西,这个迭代器可以帮助我们把数据逐一的拿到

获取迭代器的两种方案
    1. iter()内置函数可以直接拿到迭代器
    2.__iter__()特殊方法(用的少一些)
从迭代器中拿到数据:
    1.next()内置函数
    2.__next()__特殊方法
for里面一定是要拿到迭代器的,所以所有不可迭代的东西不能用for循环
for循环中一定有__next__出现

总结:迭代器本身统一了所有不同类型的遍历工作

补充:
    迭代器本身也是可迭代的

    迭代器本身的特性:
        1.只能向前,不能反复
        2.特备的节省内存
        3.惰性机制(你不访问next,它就不会执行)
'''

生成器

生成器的本质就是迭代器,并且它是一种只能迭代一次的迭代器. 生成器的基本形式:

def func():
    print(123456)
    yield  999 #yield也有返回的意思,但是和return不一样,return是立即执行函数

ret = func()
print(ret) #<generator object func at 0x108cf6660>
# ret.__next__() #执行next
print(ret.__next__())  #打印123456\n 999
def func():
    print("我是无关紧要的内容")
    yield 777
    print("我是无关紧要的内容")
    yield 888
    print("我是无关紧要的内容")
    yield 999

ret = func()
print(ret.__next__()) #我是无关紧要的内容\n 777
print(ret.__next__())#我是无关紧要的内容\n 888
print(ret.__next__())#我是无关紧要的内容\n 999

生成器的案例

这就是一个节约性能的案例,可能1000不太明显,但是要是这个数字是1E那么这段代码就非常的节约性能了。

def order():
    lst = []
    # i = 1
    for i in range(1,1000):
        lst.append(f"衣服{i}")
        if len(lst) == 50:
            yield lst
            lst = []

gen = order()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())

总结

生成器:
    生成器的本质就是迭代器

    创建生成器的两种方案:
        1.生成器函数
        2.生成器表达式
    生成器函数
        生成器函数有一个关键字yield
        生成器函数执行的时候,并不会执行函数,得到的是生成器.

        yield:只要函数中出现了yield,它就是一个生成器
            作用:
                1.可以返回数据
                2.可以分段的执行函数中的内容,通过__next__()可以执行到下一个yield位置
            优势:
                用好了,特别的节省内存
                开始追求性能了,生成器是首选