Python:可迭代对象与迭代器

news2024/11/16 16:35:24

相关阅读

Pythonicon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482


        根据Python官方文档,可迭代对象(iterable)是“一种能够逐个返回其成员项的对象”。具体来说,这种对象要么定义了一个返回迭代器(iterator)的魔术方法__iter__(),要么定义了魔术方法__getitem__(),并使用从0开始的整数索引。

        Python中的一些内置类型就是可迭代对象,比如列表(list)、元组(tuple)、range对象、字符串(str)、字典(dict)、集合(set),下面的例子检测了这些类型是否拥有__iter__()方法或__getitem__()方法:

List  = [1, 2, 3]
Tuple = (1, 2, 3)
Range = range(1, 4)
Str   = 'hello, world!'
Dict  = {'name': 'Alice', 'age': 13, 'gender': 'Female'}
Set   = {1, 2, 3}

# 检测是否包含 __getitem__ 方法
print("List has __getitem__:", hasattr(List, '__getitem__'))
print("Tuple has __getitem__:", hasattr(Tuple, '__getitem__'))
print("Range has __getitem__:", hasattr(Range, '__getitem__'))
print("Str has __getitem__:", hasattr(Str, '__getitem__'))
print("Dict has __getitem__:", hasattr(Dict, '__getitem__'))
print("Set has __getitem__:", hasattr(Set, '__getitem__'))

# 检测是否包含 __iter__ 方法
print("List has __iter__:", hasattr(List, '__iter__'))
print("Tuple has __iter__:", hasattr(Tuple, '__iter__'))
print("Range has __iter__:", hasattr(Range, '__iter__'))
print("Str has __iter__:", hasattr(Str, '__iter__'))
print("Dict has __iter__:", hasattr(Dict, '__iter__'))
print("Set has __iter__:", hasattr(Set, '__iter__'))

        结果显示,它们大多都实现了这两个魔术方法,除了集合没有实现__getitem__()方法,如下所示。

输出:
List has __getitem__: True
Tuple has __getitem__: True
Range has __getitem__: True
Str has __getitem__: True
Dict has __getitem__: True
Set has __getitem__: False
List has __iter__: True
Tuple has __iter__: True
Range has __iter__: True
Str has __iter__: True
Dict has __iter__: True
Set has __iter__: True

        collections.abc.Iterable是一个基类,可以用它检测一个对象是否拥有__iter__()方法,如下所示。

from collections.abc import Iterable
# 检测是否含有__iter__()
print("List is Iterable:", isinstance(List, Iterable))
print("Tuple is Iterable:", isinstance(Tuple, Iterable))
print("Range is Iterable:", isinstance(Range, Iterable))
print("Str is Iterable:", isinstance(Str, Iterable))
print("Dict is Iterable:", isinstance(Dict, Iterable))
print("Set is Iterable:", isinstance(Set, Iterable))
# 输出:
List is Iterable: True
Tuple is Iterable: True
Range is Iterable: True
Str is Iterable: True
Dict is Iterable: True
Set is Iterable: True

        但这不是一个可靠的检测方式,因为如果一个可迭代对象只拥有__getitem__()方法,则这种方式就会失效。一个可靠的方式是使用Python内置函数iter()。

        可迭代对象可以使用内置函数iter()转化为迭代器(iterator),iter()函数首先会尝试调用可迭代对象的__iter__()方法返回一个迭代器(是否是迭代器是根据返回对象是否拥有__next__方法检测的,如返回的不是迭代器则会产生TypeError异常: iter() returned non-iterator of type ***),如果不存在__iter__()方法,则会寻找是否有索引从0开始的__getitem__()方法并尝试创建一个迭代器,如果仍然不存在,则会引发TypeError异常。

        下面展示了一些内置类型使用iter()函数创建的迭代器,直接使用__iter__()方法也可返回迭代器,但它不检测返回的是否是迭代器,因此最好使用iter()函数。

# 检测迭代器的类型
ListIter = iter(List)    # 直接使用List.__iter__()方法也可返回迭代器
print(type(ListIter))  
TupleIter = iter(Tuple)  # 直接使用Tuple.__iter__()方法也可返回迭代器
print(type(TupleIter))
RangeIter = iter(Range)  # 直接使用Range.__iter__()方法也可返回迭代器
print(type(RangeIter))
StrIter = iter(Str)      # 直接使用Str.__iter__()方法也可返回迭代器
print(type(StrIter))
DictIter = iter(Dict)    # 直接使用Dict.__iter__()方法也可返回迭代器
print(type(DictIter))
SetIter = iter(Set)      # 直接使用Set.__iter__()方法也可返回迭代器
print(type(SetIter))

# 输出:
<class 'list_iterator'>
<class 'tuple_iterator'>
<class 'range_iterator'>
<class 'str_iterator'>
<class 'dict_keyiterator'>
<class 'set_iterator'>

        迭代器拥有__iter__()方法(用于返回自己,因此迭代器本身也是可迭代对象),和__next__()方法(用于迭代)。

        for循环其实就是迭代的过程,首先会调用iter()函数为可迭代对象创建一个未命名的迭代器,再循环的过程中调用__next__()方法进行迭代,直到迭代器耗尽,触发StopIteration异常并停止循环,并销毁未命名的迭代器。

        使用内置函数next()也可以进行迭代,它们之间的差别不大,如下所示。

# 使用列表迭代器
print(next(ListIter))
print(ListIter.__next__()) 
print(next(ListIter))
print(ListIter.__next__()) 

# 输出:
1
2
3
StopIteration Traceback (most recent call last)

        注意从 Python 3.7 开始,字典的遍历顺序一定和输入顺序一样。所以字典迭代器的迭代顺序是确定的,对字典使用iter()函数,默认返回的是针对键的迭代器,可以通过使用values()方法或items()方法明确指定想要遍历的元素,并返回相应的迭代器。

# 使用字典迭代器
print(next(DictIter))
print(next(DictIter))
print(next(DictIter))

ValueIter = iter(Dict.values())
print(next(ValueIter))
print(next(ValueIter))
print(next(ValueIter))

输出:
name
age
gender
Alice
13
Female

        集合迭代器无法保证遍历顺序,因此不应该对此有任何期待。

        下面的例子定义了一个,只含有__getitem__()方法的可迭代对象,并直接使用循环迭代,还创建了一个迭代器并用next()函数进行迭代。

class MyIterable:
    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        return self.data[index]

# 示例用法
my_iterable = MyIterable([1, 2, 3, 4, 5])

for item in my_iterable:
    print(item)

my_iterator = iter(my_iterable)
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))

输出:
1
2
3
4
5
1
2
3

        迭代器对象只能按照顺序前行,无法后退,这意味着对于一个迭代器对象,只能遍历一轮,如果想要多轮迭代,可以重新创建迭代器。

        写这篇文章的起因,是接触了神经网络框架Pytorch中的torchvision.datasets包,里面定义了很多数据集,它们是拥有__getitem__()方法的可迭代对象,因此可以使用索引访问,而dataloader是拥有__iter__()方法的可迭代对象,所以不可以使用索引访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1605458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入解析Nacos配置中心的动态配置更新技术

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在微服务架构中&#xff0c;配置管理变得尤为关键。Nacos&#xff0c;作为一个开源的、易于使用的、功能丰富的平台&#xff0c;为…

python 无处不在的二分搜索

我们知道二分查找算法。二分查找是最容易正确的算法。我提出了一些我在二分搜索中收集的有趣问题。有一些关于二分搜索的请求。我请求您遵守准则&#xff1a;“我真诚地尝试解决问题并确保不存在极端情况”。阅读完每个问题后&#xff0c;最小化浏览器并尝试解决它。 …

从计算机视觉到生命科学

人工智能技术的快速发展正在深刻影响和重塑我们的生活。作为AI领域的前沿方向,多模态大模型凭借其强大的跨域学习和推理能力,在众多行业和科学领域展现出广阔的应用前景。多模态AI指的是能够同时处理和整合文本、图像、音频、视频等不同模态数据的智能系统。这种融合不同信息源…

Java详解:GUI容器组件 | 功能组件

✎ 简介&#xff1a; Graphical User Interface&#xff08;GUI&#xff09;图形用户界面 图形界面对于用户来说在视觉上更易于接受. ✎ 关于swing: • swing是一个为java设计的GUI工具包javax.swing&#xff0c;包括了用户界面的各种组件. • swing中组件可以分为两大类&…

刷题之Leetcode19题(超级详细)

19.删除链表的倒数第N个节点 力扣题目链接(opens new window)https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 进阶&#xff1a;你能尝试使用一趟扫描实现吗&#x…

【C语言__函数栈帧的创建和销毁__复习篇9】

目录 前言 一、知识补充 二、分析创建和销毁的过程 三、前言问题回答 前言 本篇主要讨论以下问题&#xff1a; 1. 编译器什么时候为局部变量分配的空间 2. 为什么局部变量的值是随机的 3. 函数是怎么传参的&#xff0c;传参的顺序是怎样的 4. 形参和实参是什么关系 5. 函数…

Jmeter 性能压测-常见问题

1、怎么确定系统最大负载&#xff1f; 通过负载测试&#xff0c;不断增加用户数&#xff0c;随着用户数的增加&#xff0c;各项性能指标也会相应产生变化&#xff0c;当出现了性能拐点。 比如&#xff0c;当用户数达到某个数量级时&#xff0c;响应时间突然增长&#xff0c;那…

算法:期望场景;鲁棒优化

部分代码 for i1:T stst[D_DGk(i)*min_P_DG<P_DGk(i)<D_DGk(i)*max_P_DG]; end for i2:T indicatorD_DGk(i)-D_DGk(i-1); rangei:min(T,iT_up-1); st st[D_DGk(range)>indicator]; end for i2:T indicatorD_DGk(i-1)-D_DGk(i); rangei:min(T…

《QT实用小工具·二十九》托盘图标控件

1、概述 源码放在文章末尾 托盘图标控件 可设置托盘图标对应所属主窗体。 可设置托盘图标。 可设置提示信息。 自带右键菜单。 下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #ifndef TRAYICON_H #define TRAYICON_H/*** 托盘图标控件* 1. 可设置托盘图标…

书生·浦语大模型全链路开源体系-第5课

书生浦语大模型全链路开源体系-第5课 书生浦语大模型全链路开源体系-第5课相关资源LMDeploy基础配置LMDeploy运行环境下载internlm2-chat-1_8b模型使用Transformer来直接运行InternLM2-Chat-1.8B模型使用LMDeploy以命令行方式与InternLM2-Chat-1.8B模型对话设置KV Cache最大占用…

Spring Batch

Spring是一个开放源代码的J2EE应用程序框架&#xff0c;由Rod Johnson发起&#xff0c;是针对bean的生命周期进行管理的轻量级容器&#xff08;lightweight container&#xff09;。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题&#xff0c;提供了功能强大IOC、AOP及W…

线上废品回收小程序,数字化回收模式带来的发展优势

近几年&#xff0c;废品回收行业的发展如火如荼&#xff0c;不少年轻人开始进入到市场中&#xff0c;进行回收创业模式。 随着废品回收市场规模的扩大&#xff0c;关于回收的方式也越来越多样&#xff0c;为居民提供了更多的便利&#xff0c;其中线上预约回收小程序就是一种新…

Leetcode算法训练日记 | day29

一、递增子序列 1.题目 Leetcode&#xff1a;第 491 题 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&…

【配电网故障定位】基于二进制蝙蝠算法的配电网故障定位 33节点配电系统故障定位【Matlab代码#80】

文章目录 【获取资源请见文章第6节&#xff1a;资源获取】1. 配电网故障定位2. 二进制蝙蝠算法3. 算例展示4. 部分代码展示5. 仿真结果展示6. 资源获取 【获取资源请见文章第6节&#xff1a;资源获取】 1. 配电网故障定位 配电系统故障定位&#xff0c;即在配电网络发生故障的…

基于SpringBoot的在线五子连珠的设计与实现,前端采用vue框架;后端采用SpringBoot,mybatis

介绍 基于SpringBoot的在线五子连珠的设计与实现&#xff0c;主要是设计一款五子棋游戏&#xff0c;涉及登录注册的功能&#xff0c;人机对战、联机对战和积分排行榜的功能。其中人机对战中&#xff0c;电脑采用的是采用了一种基于局面分析的评分算法来确定机器人的下一步落子…

基于Python dlib的实时人脸识别,附源码

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

CSS背景设置

目录 背景颜色 背景图片 背景平铺 背景图片位置 背景图片固定 背景样式综合书写 背景色半透明 通过 CSS 背景属性&#xff0c;可以给页面元素添加背景样式。背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等 背景颜色 在CSS中可以使用bac…

Count the Values of k

目录 题目总览 思路 参考代码 原题链接&#xff1a; CF1933C Turtle Fingers: Count the Values of k 题目总览 # Turtle Fingers: Count the Values of k ## 题面翻译 给你三个**正**整数 $a$ 、 $b$ 和 $l$ ( $a,b,l>0$ )。 可以证明&#xff0c;总有一种方法可以选择*…

机器学习——模型融合:Stacking算法

机器学习——模型融合&#xff1a;Stacking算法 在机器学习中&#xff0c;模型融合是一种常用的方法&#xff0c;它可以提高模型的泛化能力和预测性能。Stacking算法&#xff08;又称为堆叠泛化&#xff09;是一种强大的模型融合技术&#xff0c;它通过组合多个基本分类器的预…

hive了解系列一

“ 随着智能手机的普及&#xff0c;互联网时代红利的爆发&#xff0c;用户数量和产生的数据也越发庞大。为了解决这个问题&#xff0c;提高数据的使用价值。 Hadoop生态系统就被广泛得到应用。 在早期&#xff0c;Hadoop生态系统就是为处理如此大数据集而产生的一个合乎成本效益…