python笔记—第N篇—python的容器、迭代器、生成器

1、容器

在python中有四种内置容器 : list,set,tuple,dictionary
即列表、元组、集合、字典

字符串str可以也算一个容器

这个没什么好介绍的~~~

2、迭代器

2.1 迭代器是什么

迭代器是一个可以记住遍历位置的对象,可以遍历诸如list,set,tuple,dictionary以及字符串等序列对象

2.2 我们先来回顾下for循环迭代

for element in [1, 2, 3]:
    print(element)
for element in (1, 2, 3):
    print(element)
for key in {'one':1, 'two':2}:
    print(key)
for char in "123":
    print(char)

image

这种访问风格清晰、简洁又方便,这也算是迭代。

2.3 从for循环到迭代器的原理

在幕后,for 语句会在容器对象上调用 iter()。 该函数返回一个定义了 next() 方法的迭代器对象,此方法将逐一访问容器中的元素。 当元素用尽时,next() 将引发 StopIteration 异常来通知终止 for 循环。

2.4 迭代器例子

2.4.1 一个例子搞懂迭代器的使用方法

逐一取出元素,并打印,就是迭代

s = 'abcdefg'
it = iter(s)
print(f"s:{s}")
print(f"it:{it}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

输出:
image

2.4.2 当超出了迭代对象时,会抛出StopIteration异常

s = 'abcdefg'
it = iter(s)
print(f"s:{s}")
print(f"it:{it}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

2.4.3 用了len(list(迭代器)),后面无法next(迭代器),会抛出StopIteration异常

s = 'abcdefg'
it = iter(s)
print(f"s:{s}")
print(f"it:{it}")
print(f"len(it):{len(list(it))}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

2.4.4 同样,可以用for循环遍历输出迭代器的值,但遍历后也无法next(迭代器),也会抛出StopIteration异常。因此我们可以认为迭代器的值只运行“用”一次

s = 'abcdefg'
it = iter(s)
print(f"s:{s}")
print(f"it:{it}")
for i in it:
    print(i)
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

在next(迭代器)之前没有“用完”迭代器的元素时,操作就是正常的,可以接着用for遍历体现。
结论:当我们迭代完 for时,如果再次执行迭代,将不会有任何数据输出。如果我们想每次执行都能迭代元素,只能每次迭代一个新对象。

s = 'abcdefg'
it = iter(s)
print(f"s:{s}")
print(f"it:{it}")

print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

for i in it:
    print(i)

image

3、生成器

3.1 生成器概念

生成器 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似于标准的函数,但当它们要返回数据时会使用 yield 语句。 每次在生成器上调用 next() 时,它会从上次离开的位置恢复执行(它会记住上次执行语句时的所有数据值)。

3.2 生成器例子

def generator_function():
    for i in range(10):
        print(f"进入一次for循环,i={i}")
        yield i

for item in generator_function():
    print(item)

image

从输出可以看出,生成器通过写yield ,现场按照一定的规律“生成”一个数。它不会像传统for循环一样一次打印完所有的值。而是要一个取一个。

3.3 生成器的和迭代器的关系——生成器也是一种迭代器

def generator_function():
    for i in range(5):
        print(f"进入一次for循环,i={i}")
        yield i

it = generator_function()
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

那就有人说了,会不会是因为yield只是单纯返回1个值,其实不是的,可以改回return试试

def generator_function():
    for i in range(5):
        print(f"进入一次for循环,i={i}")
        return i

it = generator_function()
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image
很显然是不行的,pycharm也会提示你代码有问题,输出的报错也提醒你这不是一个迭代器

3.4 对于生成器的调用方式,可以省略it = iter(容器)实例化,但加上也不会有什么影响

我们前面说的迭代器是需要用it = iter(容器)实例化一个迭代器对象的,但对于生成器来说,生成器本身就是一个迭代器,它不需要实例化,但加上也没事

def generator_function():
    for i in range(5):
        print(f"进入一次for循环,i={i}")
        yield i

it = iter(generator_function())
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

跟迭代器一样,超过了范围,无论加不加it = iter(容器)实例化,都会抛出StopIteration异常

def generator_function():
    for i in range(5):
        print(f"进入一次for循环,i={i}")
        yield i

it = generator_function()
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

def generator_function():
    for i in range(5):
        print(f"进入一次for循环,i={i}")
        yield i

it = iter(generator_function())
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")
print(f"next(it):{next(it)}")

image

posted @ 2022-11-06 10:07  JaxonYe  阅读(15)  评论(0编辑  收藏  举报