Python 迭代器介绍及作用详情

目录
  • 迭代器:初探
  • 什么是迭代器?
  • 通过迭代器进行迭代
  • 迭代器 for 循环的工作
  • 构建自定义迭代器
  • Python 无限迭代器
  • Python 迭代器的好处
  • 总结

迭代器:初探

Python 学习的人都知道,Python 中存在两种循环语句:while 和 for。for 循环可以用于 Python 中的任何序列,包括列表、元组、字符串。

>>> for x in [2013, 14, 15926]: print(x, end=' ')
...
2013 14 15926
>>>
>>> for x in (2021, 2022, 2023): print(x, end='->')
...
2021->2022->2023->
>>> for x in 'HelloWorld': print(x, end=' ')
...
H e l l o W o r l d

实际上,for 循环还能使用于任何可迭代对象。可迭代对象在 Python 中是新颖特别的概念,但实际上就是序列概念的通用化:如果对象时实际保存的序列,或者可以在迭代工具中(如 for 循环)一次产生一个结果的对象,就看做可迭代的。可以说,Python 中迭代器无处不在

什么是迭代器?

Python 中的迭代器是一个对象,用于迭代列表、元组、字典和集合等可迭代对象。Python 迭代器对象必须实现两个特殊的方法:__iter__()__next__()方法:

  • 使用 __iter__() 方法初始化迭代器对象
  • 使用 __next__() 方法进行迭代。

通过迭代器进行迭代

iter()函数依次调用 __iter__()方法,返回一个迭代器。我们使用 next() 函数手动遍历迭代器的所有项。

当我们到达终点并且没有更多数据要返回时,它将引发 StopIteration异常。

下面是一个例子:

# define a list
my_list = [2013, 14, 15926]

# get an iterator using iter()
my_iter = iter(my_list)
# iterate through it using next()

# Output: 2013
print(next(my_iter))

# Output: 14
print(next(my_iter))

# next(obj) is same as obj.__next__()
# Output: 15926
print(my_iter.__next__())
# This will raise error, no items left
next(my_iter)

依次执行上面的代码,输出如下:

2013
14
15926
Traceback (most recent call last):
File "<string>", line 24, in <module>
next(my_iter)
StopIteration

一种更优雅的自动迭代方式是使用 for 循环。使用它,我们可以迭代任何可以返回迭代器的对象,例如列表、字符串、文件等。

>>> for element in my_list:
... print(element)
...
2013
14
15926

迭代器 for 循环的工作

正如我们在上面的示例中看到的,for 循环能够自动遍历列表。

实际上 for 循环可以迭代任何可迭代对象。让我们仔细看看 for 循环是如何在 Python 中实际实现的。

for element in iterable:
# do something with element

实际实现为:

# create an iterator object from that iterable
iter_obj = iter(iterable)

# infinite loop
while True:
try:
# get the next item
element = next(iter_obj)
print(element)
# do something with element
except StopIteration:
# if StopIteration is raised, break from loop
break

所以在内部,for 循环通过在可迭代对象上调用 iter()创建一个迭代器对象 iter_obj。具有讽刺意味的是,这个 for 循环实际上是一个无限的 while 循环。

在循环内部,它调用 next()来获取下一个元素并使用该值执行 for 循环的主体。在所有项目耗尽后,StopIteration被引发,内部捕获并结束循环。请注意,任何其他类型的异常都会通过。

构建自定义迭代器

在 Python 中从头开始构建迭代器很容易。我们只需要实现 __iter__() __next__() 方法。

__iter__() 方法返回迭代器对象本身。如果需要,可以执行一些初始化。

__next__() 方法必须返回序列中的下一项。在到达终点时以及在随后的调用中,它必须引发 StopIteration

class PowTwo:
"""Class to implement an iterator
of powers of two"""
def __init__(self, max=0):
self.max = max

def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration
# create an object
numbers = PowTwo(3)
# create an iterable from the object
i = iter(numbers)
# Using next to get to the next iterator element
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))

输出结果:

1
2
4
8
Traceback (most recent call last):
File "/Users/yuzhou_1su/go/src/iterdemo.py", line 32, in <module>
print(next(i))
StopIteration

我们还可以使用 for 循环来迭代我们的迭代器类。

>>> for i in PowTwo(5):
... print(i)
...
1
2
4
8
16
32

Python 无限迭代器

迭代器对象中的项目不必耗尽。可以有无限的迭代器(永远不会结束)。在处理此类迭代器时,我们必须小心。

这是一个演示无限迭代器的简单示例。

内置函数 iter()可以使用两个参数调用,其中第一个参数必须是可调用对象(函数),第二个参数是哨兵。迭代器调用这个函数,直到返回的值等于哨兵。

>>> int()
0
>>> inf = iter(int,1)
>>> next(inf)
0
>>> next(inf)
0

我们可以看到 int()函数总是返回 0。因此将它作为 iter(int,1)传递将返回一个迭代器,该迭代器调用 int()直到返回值等于 1。这永远不会发生,我们得到一个无限迭代器。

我们还可以构建自己的无限迭代器。

理论上,以下迭代器将返回所有奇数:

class InfIter:
"""Infinite iterator to return all
odd numbers"""

def __iter__(self):
self.num = 1
return self

def __next__(self):
num = self.num
self.num += 2
return num
>>> a = iter(InfIter())
>>> next(a)
1
>>> next(a)
3
>>> next(a)
5
>>> next(a)
7

在对这些类型的无限迭代器进行迭代时,请小心包含终止条件。如上所示,我们可以得到所有奇数,而无需将整个数字系统存储在内存中。理论上,我们可以在有限的内存中拥有无限的项目。

Python 迭代器的好处

使用迭代器的好处是可以节省资源:

  • 代码减少。
  • 代码冗余得到极大解决。
  • 降低代码复杂度。
  • 它为编码带来了更多的稳定性。

总结

Python 的迭代器提供稳定和灵活的代码。迭代器和可迭代对象的区别:

  • Iterable是一个可以迭代的对象。它在传递给 iter()方法时生成一个迭代器。
  • Iterator是一个对象,用于使用 __next__()方法对可迭代对象进行迭代。迭代器有 __next__() 方法,它返回对象的下一项。

请注意,每个迭代器也是一个可迭代的,但不是每个可迭代的都是一个迭代器。

例如,列表是可迭代的,但列表不是迭代器。可以使用函数 iter() 从可迭代对象创建迭代器。

为了实现这一点,对象的类需要一个方法 __iter__,它返回一个迭代器,或者一个具有从 0 开始的顺序索引的 __getitem__方法。但其本质也是实现了 __iter__方法。

到此这篇关于Python 迭代器介绍及作用详情的文章就介绍到这了,更多相关Python 迭代器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文搞懂​​​​​​​python可迭代对象,迭代器,生成器,协程

    目录 设计模式:迭代 python:可迭代对象和迭代器 为什么要有生成器? python的生成器实现 协程 设计模式:迭代 迭代是一种设计模式,解决有序便利序列的问题.通用的可迭代对象需要支持done和next方法. 伪代码如下: while not iterator.done(): item = iterator.next() ..... python:可迭代对象和迭代器 python的可迭代对象需要实现__iter__()方法,返回一个迭代器.for循环和顶级函数iter(obj)调用obj

  • 详解Python之可迭代对象,迭代器和生成器

    目录 一.概念描述 二.序列的可迭代性 三.经典的迭代器模式 四.生成器也是迭代器 五.实现惰性迭代器 六.使用生成器表达式简化惰性迭代器 总结 一.概念描述 可迭代对象就是可以迭代的对象,我们可以通过内置的iter函数获取其迭代器,可迭代对象内部需要实现__iter__函数来返回其关联的迭代器; 迭代器是负责具体数据的逐个遍历的,其通过实现__next__函数得以逐个的访问关联的数据元素;同时通过实现__iter__来实现对可迭代对象的兼容; 生成器是一种迭代器模式,其实现了数据的惰性生成,即

  • Python学习之迭代器详解

    目录 什么是迭代器 如何生成迭代器 迭代器函数 - iter() 函数 与 next() 函数 可迭代的对象 生成迭代器 迭代器的用法 - 演示案例 什么是迭代器 迭代是 python 中访问集合元素的一种非常强大的一种方式.迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源.迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完.迭代器有两个方法:iter()和 next()方法. 这么解释可能不太直观,我们以生活

  • python三大器之迭代器、生成器、装饰器

    目录 迭代器 生成器 装饰器(非常实用!) 迭代器 聊迭代器前我们要先清楚迭代的概念:通常来讲从一个对象中依次取出数据,这个过程叫做遍历,这个手段称为迭代(重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值).可迭代对象(iterable):是指该对象可以被用于for…in…循环,例如:集合,列表,元祖,字典,字符串,迭代器等. 在python中如果一个对象实现了 __iter__方法,我们就称之为可迭代对象,可以查看set\list\tuple…等源码内部均实现了__iter

  • Python迭代器的实现原理

    目录 前言: 迭代器的创建 迭代器的底层结构 迭代器是怎么迭代元素的? 小结 前言: 在Python里面,只要类型对象实现了__iter__,那么它的实例对象就被称为可迭代对象(Iterable),比如字符串.元组.列表.字典.集合等等.而整数.浮点数,由于其类型对象没有实现__iter__,所以它们不是可迭代对象. from typing import Iterable print( isinstance("", Iterable), isinstance((), Iterable)

  • python中的生成器、迭代器、装饰器详解

    一.装饰器 由于一个函数能实现一种功能,现在想要在不改变其代码的情况下,让这个函数进化一下,即能保持原来的功能,还能有新的"技能",怎么办? 现已经存在一个自定义的函数func1 def func1(): print('hello,world!') 让func1进化一下:(继承func1之前的所有功能,而且还有新的‘技能’) 效果和下面定义的函数func2效果是一样的 def func2(): func1() #调用func1,即可保持func1这一函数的所有的功能都被这个新的函数继承

  • python的迭代器,生成器和装饰器你了解吗

    python 迭代器与生成器,装饰器 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器有两个基本的方法:iter() 和 next(). 字符串,列表或元组对象都可用于创建迭代器: list1=[1,2,3] s=iter(list1) # 创建迭代器对象 print(next(s)) # 输出迭代器的下一个元素 print(next(s)) print(next(s)) 直到计算出最后一个元素,没有更多的元素时,抛出StopIteration的错误 迭代器对象可以使用

  • Python 迭代器Iterator详情

    目录 前言 1. 什么是迭代器? 2. 迭代器类型 3. 迭代器分类 容器迭代器 遍历迭代器 自定义迭代器 总结 前言 当我们需要对列表(list).元组(tuple).字典(dictionary)和集合(set)的元素进行遍历时,其实Python内部都是启动迭代器来完成操作的. 迭代器(Iterator)并非Python独有的,在C++和Java中也出现了此概念.迭代器可以帮助我们解决面对复杂的数据场景时,快速简便的获取数据. 1. 什么是迭代器? 迭代器是一个表示数据流的对象,当我们调用ne

  • python列表生成器常用迭代器示例详解

    目录 列表生成式基础语法 1. 使用列表生成式,一行解决for循环 2. 双层循环 3. 加判断语句,条件过滤 4. 加入函数 5. 常见几种迭代器:range. zip . enumerate . filter . reduce 列表生成式基础语法 [exp for iter_var in iterable (if conditional)] 原理: 首先迭代 iterable 里所有内容,每一次迭代,都把iterable里相应的内容放在iter_var中,再把表达式exp应用该iter_va

  • Python 迭代器介绍及作用详情

    目录 迭代器:初探 什么是迭代器? 通过迭代器进行迭代 迭代器 for 循环的工作 构建自定义迭代器 Python 无限迭代器 Python 迭代器的好处 总结 迭代器:初探 Python 学习的人都知道,Python 中存在两种循环语句:while 和 for.for 循环可以用于 Python 中的任何序列,包括列表.元组.字符串. >>> for x in [2013, 14, 15926]: print(x, end=' ') ... 2013 14 15926 >>

  • 五分钟带你搞懂python 迭代器与生成器

    前言 大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法.对于获取数据的方法而言,我们会一种就足够了.但是在我后来Python的使用以及TensorFlow等学习使用当中,我发现很多地方都用到了迭代器和生成器,或者是直接使用,或者是借鉴了思路.今天就让我们仔细来看看,它们到底是怎么回事. 迭代器 我们先从迭代器开始入手,迭代器并不是Python独有的概念,在C++和Java当中都有itera

  • Python中的for循环详情

    目录 1.可迭代对象 1.1什么是可迭代对象 1.2怎么判断 2.字符串的for循环 3.列表的for循环 4.元组的for循环 5.字典的for循环 5.1keys() 5.2 values() 5.3 items() 6.range函数的for循环 6.1基础案例 6.2找出100以内能够被5整除的数 6.3高斯求和 7.多个for语句 8.列表推导式 9.for-else 10.实现三角阵列 11.99乘法表 for语句实际上解决的是循环问题.在很多的高级语言中都有for循环(for lo

  • python 名称空间与作用域详情

    目录 一.名称空间 1.1 内置名称空间 1.2 全局名称空间 1.3 局部名称空间 1.4 加载顺序 1.5 查找顺序 二.作用域 2.1 全局作用域 2.2 局部作用域 2.4 函数对象+作用域应用 三.补充知识点 3.1 global关键字 3.2 nonlocal关键字 3.3 注意点 函数内部的函数只能在函数内部调用,不能在函数外部调用,通过接下来的学习你将会知道为什么会出现这种情况. 一.名称空间 名称空间(name spaces):在内存管理那一章节时,我们曾说到变量的创建其实就是

  • Python 数字转化成列表详情

    目录 1. digitize 2. Python判断对象是否可迭代 本篇阅读的代码实现了将输入的数字转化成一个列表,输入数字中的每一位按照从左到右的顺序成为列表中的一项. 本篇阅读的代码片段来自于30-seconds-of-python. 1. digitize def digitize(n): return list(map(int, str(n))) # EXAMPLES digitize(123) # [1, 2, 3] 该函数的主体逻辑是先将输入的数字转化成字符串,再使用map函数将字符

  • Python面向对象中的封装详情

    目录 一封装的概念 二_和__对属性和方法的私有化 1.单下划线_ 2.双下划线__ 3.子类中访问父类的私有属性和私有方法 三访问及修改类的私有属性和私有方法 1.自定义公有方法 2.property 一 封装的概念 封装其实在我们的生活中处处都是,如电视机,电脑,手机等物品.我们通常只能看到其外部的形状,以及使用他们提供的功能,并不能看到其内部复杂的硬件组成,这些都是封装好的,不能让我们看到,避免我们的一些“特殊”操作,使其不能正常工作.编程源于生活.在python中也有对对象的封装操作,使

  • python 名称空间与作用域详情

    目录 一.名称空间 1.1 内置名称空间 1.2 全局名称空间 1.3 局部名称空间 1.4 加载顺序 1.5 查找顺序 二.作用域 2.1 全局作用域 2.2 局部作用域 2.4 函数对象+作用域应用 三.补充知识点 3.1 global关键字 3.2 nonlocal关键字 3.3 注意点 函数内部的函数只能在函数内部调用,不能在函数外部调用,通过接下来的学习你将会知道为什么会出现这种情况. 一.名称空间 名称空间(name spaces):在内存管理那一章节时,我们曾说到变量的创建其实就是

  • Python函数和文件操作详情

    目录 前言 一.函数 二.自定义函数 1.创建函数 2.调用函数 3.函数默认值 4.收集函数(可变函数) 5.全局与局部 6.匿名函数lambda 7.内嵌函数 三.常用内置函数 1.max和min 2.abs 3.round 4.pow 5.divmod 6.help 7.filter 8.map 四.文件 1.read()方法读取 2.readline()方法 3.readlines()方法 4.遍历文件对象读取 5.文件的写入 6.文件关闭 7.with方式 8.pickle 前言 本篇

  • Python+ Flask实现Mock Server详情

    目录 一.Mock介绍 1.什么是Mock 2.Mock的三种典型应用场景 3.Mock的作用 4.Mock实现的3种方式 二.环境搭建 三.Mock的案例 一.Mock介绍 1.什么是Mock 模拟接口 接口Mock测试:在接口测试中,对于某些不容易构造或者不容易获取的接口,可以用一个模拟接口来代替 2.Mock的三种典型应用场景 依赖的接口未实现 依赖的接口响应速度慢 针对接口模拟各种异常 3.Mock的作用 可以用来解除测试对象对外部服务的依赖,使得测试用例可以独立运行 模拟异常逻辑,异常

随机推荐