首页 > 编程语言 >Python高频面试题——迭代器和可迭代对象

Python高频面试题——迭代器和可迭代对象

时间:2023-09-27 10:35:46浏览次数:60  
标签:__ 面试题 迭代 Python iter next 对象 print


Python高频面试题——迭代器和可迭代对象_迭代器模式

 

无论是面试测试还是运维涉及到python编码岗位时,迭代器和可迭代对象都是绕不开的一个问题,本文对这两个概念进行重点讲解,本文从什么是迭代讲起,然后介绍迭代器和可迭代对象二者的区别,最后通过for 循环和自定义迭代器来加深读者对这两个概念的理解,只要认真阅读完文章,相信一定会帮助到大家,文章有点长,建议首收藏!

迭代

关于迭代,维基百科是这样子定义的:迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。

在程序中,迭代是一种遍历集合元素的方式,我们最常用的迭代应用如下:

for i in [1,2,3]:
   print(i)

输出:

1

2

3

可迭代对象(iterable)

只要实现 __ iter __ 方法或者实现 __ getitem __方法而且其参数从0开始索引,那么该对象就是可迭代对象(iterable)。

Python 中的大多数内置数据结构(容器)都是可迭代对象,比如list、dict、tuple、set、string。创建一个可迭代对象的实例如下:

class IterableDemo(object):
     def __init__(self, components):
          self.components = list(components)
     def __iter__(self):
          return iter(self.components)
V1 = IterableDemo([1, 2, 3])
for i in V1:
    print(i)

输出

1

2

3

可以看到实例IterableDemo进行了迭代,该对象之所以能迭代,是因为实现了__ iter __ ()方法。当使用for循环时候,解释器会检查对象是否有__ iter __ ()方法,有的话就是调用它来获取一个迭代器。所以没有 __ iter __ ()方法但实现了__ getitem __ (),解释器会创建一个迭代器,尝试从0开始按顺序遍历元素。如果尝试失败,Python便会抛出TypeError错误。

看下面这个list的例子,l=[1,2,3]。这里 l是一个可迭代对象。

我们可以通过方法__iter__()和函数iter把list(可迭代对象)转变成list迭代器对象,代码如下

print(type(l))
print(type(l.__iter__()))
print(type(iter(l)))

输出

<class 'list'>

<class 'list_iterator'>

<class 'list_iterator'>

我们可以看到,list变成了list_iterator,证明list是可迭代对象!

a=123456

print(type(iter(a)))

输出

TypeError: 'int' object is not iterable

可见int 类型是不可迭代对象,也就是说调用iter(对象)函数,如果该对象不可迭代,就会抛出TypeError的错误。

迭代器(iterator)

Python 中的迭代器是一个可以迭代的对象,一个每次仅仅返回一个元素的对象。从技术上讲,Python 迭代器对象必须实现两个魔法方法:__iter__() 和 __next__()方法,统称为迭代器协议(iterator protocol)。

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用 in , not in 关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特列并不是所有的元素都放在内存)在Python中,常见的容器对象有:list、dequeue、set、dict、Counter、tuple、str等等。尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是 可迭代对象 赋予了容器这种能力,当然并不是所有的容器都是可迭代的(Bloom filter容器不可以迭代)。

我们执行以下代码,创建x 和y两个独立的迭代器。

l=[1,2,3]
x=iter(l)
y=iter(l)
print("y第一次调用:"+str(next(y)))
print("x第一次调用:"+str(next(x)))
print("y第二次调用:"+str(next(y)))
print("x第二次调用:"+str(next(x)))

输出

y第一次调用:1

x第一次调用:1

y第二次调用:2

x第二次调用:2

证明了

1. x、y是两个独立的迭代器,彼此不影响

2. 迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,调用next,每次都是按顺序获取对应的元素

那么究竟什么是迭代器呢?

迭代器是一个可以记住遍历位置的对象,其内部有一个状态用于记录迭代所在的位置,以便下次迭代时候能取出正确的元素。迭代器就像一个懒人一样,当你需要数据时候才会返回给你,否则就在等待下一次的调用。

迭代器技术主要应用在哪些地方呢?主要包括:

• for 循环

• 构建和扩展集合类型

• 逐行遍历文本文件

• 列表推导、字典推导和集合推导

• 元组拆包

• 调用函数时,使用*拆包

迭代器和可迭代对象总结

共性:他们都可以通过循环的形式进行迭代;

迭代器是可迭代对象, 但是可迭代对象不一定是迭代器,例如list是可迭代对象,但不是迭代器;

可以通过iter(可迭代对象)的方法来生成迭代器;

可迭代对象需要实现 __ iter __ 方法或者实现 __ getitem __方法而且其参数从0开始索引。注意可迭代对象不一定实现__ next__方法;

迭代器需要同时实现__ iter __ 方法和__next__ 方法,当使用next()函数时会调用__next__方法。

举一个经典的例子把

l=[1,2,3]
print(next(l))

输出error:

print(next(l))

TypeError: 'list' object is not an iterator

可见,list不是一个迭代器,因为他没有实现__next__方法

接下来执行代码,print(next(iter(l)))

输出

1

可见通过iter(l) 生成了迭代器,因此next操作可以顺利进行

for i in (iterable)的内部实现

在大多数情况下,我们不会一次次调用next方法去取值,而是通过 for i in (iterable)的方式,如下图:

Python高频面试题——迭代器和可迭代对象_迭代器模式_02

循环背后的原理又是什么呢?

调用iter(容器对象,即可迭代对象,即上图中的x=[1,2,3])函数生成迭代器(如果调用成功)

通过迭代器的__next__()方法访问容器元素

如果没有元素了,将抛出StopIteration exception

循环捕获StopIteration exception后就会终止循环

自定义迭代器

如果想自定义迭代器,需要实现__iter_和__next__两个方法

from collections.abc import Iterable
class MyIterator:
     last = 0
     def __iter__(self):
          return self
     def __next__(self):
         self.last += 1
         if self.last > 5:
             raise StopIteration
         return self.last
my= MyIterator()
print(isinstance(my,Iterable))
for i in my:
print(i)

输出:

True

1

2

3

4

5

从输出结果可以看出my 是iterable对象,并完成了遍历工作!

大家可以自定义一个类,里面不实现__iter_和__next__两个方法,例如

class Demo:
    pass
demo= Demo()
print(type(iter(demo)))

输出:

TypeError: 'Demo' object is not iterable

原创不易,如果文章帮到了你,劳烦点赞转发!

标签:__,面试题,迭代,Python,iter,next,对象,print
From: https://blog.51cto.com/liwen629/7621182

相关文章

  • Python爬虫-爬取百度搜索结果页的网页标题及其真实网址
    共两个依赖的需提前安装的第三方库:requests和bs4库cmd命令行输入安装requests库:pip3install-ihttps://pypi.douban.com/simplerequests安装bs4库:pip3install-ihttps://pypi.douban.com/simplebeautifulsoup4 本微项目源文件下载地址:https://wwuw.lanzouj.com/i1Au51......
  • Python 图片并行下载
    需求:有大量图片的url需要将其快速下载到本地技术点:采用编写并发代码的库asyncio以及基于asyncio实现的HTTP框架aiohttppipinstallasynciopipinstallaiohttp代码如下:importjsonimportosimportrequestsimportaiohttpimportasyncioimage_save_dir="images"......
  • Python面试高频问题:修改list中某个元素时的坑
    在Python面试中经常会考这样一个题目,遍历列表,如果列表中有某某元素,那么将其替换成"test"。题目看似简单,其实有个坑在里面!从面试结果来看,大多数同学都会这样写:l=["a","b","c"]foriinl:if"a"==i:i="test"print(l)运行后,大家会发现输出的l值还是['a',......
  • python range中的步长必须是整数 numpy则可以是小数
    >>>foriiinrange(1,10,0.1): print(ii)Traceback(mostrecentcalllast):File"<pyshell#4>",line1,in<module>foriiinrange(1,10,0.1):TypeError:'float'objectcannotbeinterpretedasaninteger>>......
  • Python脚本连接Oracle数据库并验证成功
    #yaml文件存储数据->root\Data\oracle_admin_f_shozaiko.yaml#TestDataforOracleDB:ADMIN->F_SHOZAIKO-name:connecttoOraclerequest:uname:adminupwd:P823!ApoLhost:rf-oms.cbfvvrud0bld.ap-northeast-1.rds.amazonaws.com:1521/rfomsqu......
  • python学习框架
    Python简介与安装Python的历史与特点Python的安装与配置Python基础语法变量与数据类型运算符与表达式控制结构(条件判断与循环)函数与模块错误处理与异常Python数据结构列表(List)元组(Tuple)集合(Set)字典(Dictionary)Python面向对象编程类与对象继承与多态......
  • Python的Selenium库:鼠标滚动和操作弹出窗口
    Selenium是一个用于自动化web应用测试的开源工具。通过Selenium,我们可以模拟真实用户的操作,如点击、输入、滚动页面等,来测试web应用的稳定性和可靠性。PythonSelenium库是Selenium的一个分支,可以方便地与Python语言结合使用。在PythonSelenium库中,元素定位和文本输入是最常用的......
  • 使用PyCharm敲出你的第一行python代码
    首先安装python解释器国内镜像https://registry.npmmirror.com/binary.html?path=python/   找到软件开始安装   然后下载python开发工具https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows&code=PCC     ......
  • Python datetime 的坑以及时间处理的经验
    最近遇到一个"bug",就是本地datetime的时间上传到数据库,总发现时间显示不对……经过一番痛苦的排查之后,我发现原来是datetime.now()在获取事件信息时,不会添加当前的时区信息。也就是说,获得的结果虽然时分秒和电脑显示一致,但是时区信息为默认的UTC而非我们真正的UTC+8,因此这......
  • 理论概念-常见嵌入式岗位面试题
    一、问题一:结合阅读ARMQ、STM32技术手册,深入思考STM32F103系列芯片的地址映射和寄存器映射原理,GPIO端口的初始化设置的一般步骤。回答:1)嵌入式C程序代码对内存(RAM)中的各变量的修改操作,与对外部设备(寄存器--->对应相关管脚)的操作有哪些相同与差别?2)为什么51单片机的LED点灯......