PYTHON 迭代器与生成器

1.1 迭代器

  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter() 和 next()。
  • 字符串,列表或元组对象都可用于创建迭代器:
  • 类型:collections.abc.Iterator

迭代器对象(Iterator),是一个包括__next__()方法的对象,它返回下一个值,如果没有值了抛出一个StopIteration的异常抛出

1.2 迭代器相关函数

iter()函数创建迭代器,前提是对象是一个可迭代对象。

next(iterator) # 取出下一个值,到尾部抛出StopIteration异常

from collections.abc import Iterator

c = [1,2,3]
it = iter(c)  # 用iter()方法创建迭代器
print(isinstance(it,Iterator))  #  测试是不是迭代器对象

print(next(it))
print(next(it))
print(next(it))
print(next(it))  # 没有了,抛出:StopIteration异常

迭代器对象可以用循环进行遍历:

c = [1,2,3]
it = iter(c)
for i in it:
    print(i, end=' ')  # 1 2 3
    
it = iter(c)
while True:
    try:
        print(next(it), end = ' ') # 1 2 3 
    except StopIteration:
        break
函数 说明
all(i) 如果元素都是True,结果为True
any(i) 如果元素有一个是True,结果为True
len(i) 长度
max(i) 最大值
min(i) 最小值
sum(i)
range(起始,结束,步长) 生成整数迭代器
* 迭代器拆分:fun(*range(1,5)) 相当于 1,2,3,4
zip 生成元组迭代: zip([1,2],[3,4],[5,6])
reversed(i) 返回一个反序迭代器
sorted(i,key=函数, reverse=False) 排序,reverse为反序, key=函数
a = [1,-3,-5,6,8,-100,7]

def my_abs(value):
    if value < 0:
        value *= -1
    return value

b = sorted(a,key=my_abs)  # 注意这个函数对元素计算,并确定位置,但不修改其值,只确定位置

print(b) # [1, -3, -5, 6, 7, 8, -100]

1.3 自定义迭代器

一个类想要实现迭代器,需要实现两个方法:

  • __iter__() 返回迭代器对象,是对象自己的引用
  • __next__() 返回下一个值,结尾抛出异常:StopIteration
class Even:
    "偶数序列0,2,4,..."
    def __init__(self):
        self.number = 0
    
    def __iter__(self): 
        self.number = 0
        return self
    
    def __next__(self):
        if self.number <= 100:
            even_value = self.number
            self.number += 2
            return even_value
        else:
            raise StopIteration

for i in Even():
    print(i, end=' ')

1.4 迭代器和可迭代对象

可迭代对象是一个装数据的容器,只要实现了__iter()__就是可迭代对象,它反回一个迭代器。从类型上区分是:

迭代器需要实现__next()__方法和__iter()__方法。

类型上区分:

  • collections.abc.Iterator 迭代器
  • collections.abc.Iterable 可迭代对象

可迭代对象是一种通过迭代器就可以访问其容器中的数据,而迭代器是封装了如何访问的方法,这样外部只需要用最简单的方法就可以访问容器中的数据。

# 定义可迭代对象
class IterableObject:
    def __init__(self):
        self.list = [1, 2, 3, 4, 5]

    def __iter__(self):
        return IteratorObject(self.list)  # 返回迭代器对象


# 定义迭代器
class IteratorObject:

    def __init__(self, p_list):
        self.list = p_list
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.list):
            raise StopIteration
        else:
            current_value = self.list[self.index]
            self.index += 1
            return current_value


obj = IterableObject()

for i in obj:
    print(i)

1.5 生成器

生成器是一种特殊的迭代器,他占用内存少,同时能通过next()迭代出元素。

类型:collections.abc.Generator

1.5.1 创建生成器

可以通过两种方法创建:

  • 第一种和列表推导式一样,把[]换成()就行
from collections.abc import Iterable, Iterator, Generator

gen = (i for i in range(5))
print(type(gen))  # <class 'generator'>

# 可以看出生成器就是迭代器也是可迭代对象
print(isinstance(gen, Iterable))  # True
print(isinstance(gen, Iterator))  # True
print(isinstance(gen, Generator))  # True
  • 第二种方法是用yield把一个函数变成生成器函数

yield相当于return,程序执行到yield时返回后面的值,但函数不结束,而是暂停了。下次调用时会从yield之后的代码执行。

def numbers(begin, end):
    while begin < end:
        yield begin
        begin += 1

n = numbers(10,12)
print(next(n))  # 10
print(next(n))  # 11
print(next(n))  # StopIterator


for i in numbers(10, 20):
    print(i, end=' ')  # 10 11 12 13 14 15 16 17 18 19

生成器会占用很少的内存,实际上是拿时间换空间,会占用更多的CPU资源

a = [i for i in range(100)]
print(a.__sizeof__())  # 904
a = (i for i in range(100))
print(a.__sizeof__())  # 96

1.6 总结

  • 可迭代对象:是一种容器,可以存放元素,自已无法实现迭代取值,需要有迭代器。实现了__iter__()方法
  • 迭代器:是一种工具对象,用于迭代取值,实现了__iter__()方法和__next__()方法。
  • 生成器:是一种函数对象,只保存一个值,通过计算返回下一个值,实现了__iter__()方法和__next__()方法。
posted @   叁只小羊  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示