首页 > 其他分享 >迭代器

迭代器

时间:2024-09-25 09:50:25浏览次数:8  
标签:__ 迭代 nums self iter print

为什么学习迭代器

如何for循环自定义实例对象

class Student:
  def __init__(self):
    self.students = []
  def add_student(self, name, age):
    self.students.append({
      "name": name,
      "age": age
    })

s = Student()
s.add_student('小明', 23)
s.add_student('小黑', 20)

# 如何实现for循环自定义实例对象?
for item in s:
  print(item)
# 报错
TypeError: 'Student' object is not iterable

什么是迭代?

迭代是访问集合元素的一种方式

# 字符串
my_str = 'hello'
for i in my_str:
  print(i)

# 列表
my_list = [1,2,3,4]
for i in my_list:
  print(i)

可迭代对象

可以被for-in遍历的都是可迭代对象

验证数据类型是否可以被迭代

from collections.abc import Iterable

# True 字符串
print(isinstance('12', Iterable))

# True 列表
print(isinstance([1,2], Iterable))

# True 元组
print(isinstance((1,2), Iterable))

# True 集合
print(isinstance({1,2}, Iterable))

# True 字典
print(isinstance({'name':'alex'}, Iterable))

# False 整数
print(isinstance(1, Iterable))

# False浮点数
print(isinstance(1.1, Iterable))

迭代器

迭代器是一个可以记住遍历的位置的对象。迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

可迭代对象的本质

可迭代对象进行迭代的过程,发现每迭代一次都会返回对象中的下一条数据,一直向后直到取完所有数据。

在每一次迭代过程中需要有一个『东西』来记住访问到第几条数据了,这个『东西』被称为迭代器(Iterator)

获取可迭代对象的迭代器

通过iter()能够得到一个可迭代对象的 迭代器

from collections.abc import Iterator

nums_list = [11, 22, 33, 44]
# 提取迭代器
nums_iter = iter(nums_list)

print(f"nums_list: {type(nums_list)}")  # nums_list: <class 'list'>
print(f"nums_iter: {type(nums_iter)}")  # nums_iter: <class 'list_iterator'>

print("nums_list", isinstance(nums_list, Iterator)) # nums_list False
print("nums_iter", isinstance(nums_iter, Iterator)) # nums_iter True

获取迭代器数据

通过iter()能够得到一个可迭代对象的 迭代器,可以通过next()函数多次提取迭代器中的数据

nums_list = [11, 22, 33, 44]
# 提取迭代器
nums_iter = iter(nums_list)

print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
11
22
33
44

StopIteration异常

可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据

nums_list = [11, 22]
# 提取迭代器
nums_iter = iter(nums_list)

print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
11
22
# 取不到之后会报StopIteration错误
Traceback (most recent call last):
  File "提取可迭代对象的迭代器.py", line 19, in <module>
    print(next(nums_iter))
StopIteration

实现for循环

for循环的过程就是通过iter()提取可迭代对象的迭代器,然后通过next提取数值,直到StopIteration异常抛出后停止迭代

nums_list = [11, 22]
# 提取迭代器
nums_iter = iter(nums_list)

while True:
    try:
        print(next(nums_iter))
    except StopIteration as e:
        print(f"e: {e}")
        break
11
22
33
44
e: 

自定义"迭代器"

__iter__方法

拥有__iter__的对象一定是可迭代对象

from collections.abc import Iterable

class MyList1:
    pass

class MyList2:
    def __iter__(self):
        pass

m1 = MyList1()
m2 = MyList2()

# 检测是否是[可迭代对象]
print(isinstance(m1, Iterable)) # False
print(isinstance(m2, Iterable)) # True

__next__方法

在使用next()函数的时候,就是调用迭代器的__next__方法。

一个类实现了__iter____next__方法,生成的对象就是迭代器

from collections.abc import Iterable, Iterator

class MyIterable:
    def __iter__(self):
        # 当使用iter()函数时,会自动执行类中的__iter__方法,返回一个迭代器对象
        print(f"MyIterable iter")
        return MyIterator()

class MyIterator:
    def __iter__(self):
        pass
    def __next__(self):
        # 当使用next()函数时,会自动执行类中的__next__方法
        print(f"MyIterator next")

        
my = MyIterable()   # 获取可迭代对象
my_iter = iter(my)  # 获取迭代器

# 可迭代对象不一定是迭代器
print("my是否是可迭代对象 ", isinstance(my, Iterable)) # True
print("my是否是迭代器 ", isinstance(my, Iterator)) # False

# 迭代器一定是可迭代对象
print("my_iter是否是可迭代对象 ", isinstance(my_iter, Iterable)) # True
print("my_iter是否是迭代器 ",isinstance(my_iter, Iterator)) # True

next(my_iter)
MyIterable iter
my是否是可迭代对象  True
my是否是迭代器  False
my_iter是否是可迭代对象  True
my_iter是否是迭代器  True
MyIterator next

验证list

from collections.abc import Iterable, Iterator

l = [1,2,3]
l_iter = iter(l)
print("l是否是可迭代对象 ", isinstance(l, Iterable)) # True
print("l是否是迭代器 ", isinstance(l, Iterator)) # False
print("l_iter是否是可迭代对象 ", isinstance(l_iter, Iterable)) # True
print("l_iter是否是迭代器 ",isinstance(l_iter, Iterator)) # True
l是否是可迭代对象  True
l是否是迭代器  False
l_iter是否是可迭代对象  True
l_iter是否是迭代器  True

案列

迭代器

class Student:
    def __init__(self):
        self.index = 0
        self.students = []
        
    def add_student(self, name, age):
        info = {
            "name": name,
            "age": age
        }
        self.students.append(info)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.students):
            item = self.students[self.index]
            self.index += 1 
            return item 
        self.index = 0
        raise StopIteration
            

stu = Student()
stu.add_student('小明', 23)
stu.add_student('小黑', 20)

# 如何实现for循环自定义实例对象?
for item in stu:
    print(item)
{'name': '小明', 'age': 23}
{'name': '小黑', 'age': 20}

可迭代对象+迭代器

class Student:
    def __init__(self):
        self.students = []
        
    def add_student(self, name, age):
        info = {
            "name": name,
            "age": age
        }
        self.students.append(info)

    def __iter__(self):
        return StudentIter(self)

class StudentIter:
    def __init__(self, obj):
        self.obj = obj
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
      	# 判断可迭代对象的长度
        if self.index < len(self.obj.students):
            item = self.obj.students[self.index]
            self.index += 1
            return item
        # 如果index超出长度,报StopIteration
        self.index = 0
        raise StopIteration

stu = Student()
stu.add_student('小明', 23)
stu.add_student('小黑', 20)
# 如何实现for循环自定义实例对象?
for item in stu:
    print(item)
{'name': '小明', 'age': 23}
{'name': '小黑', 'age': 20}

标签:__,迭代,nums,self,iter,print
From: https://www.cnblogs.com/lxd670/p/17629277.html

相关文章

  • 如何根据单独列表的内容迭代输入
    我有2个功能。我的目标是要求用户连接一些预先定义的电缆(根据他们正在运行的具体测试),确认他们已完成此操作,然后要求用户确认他们希望使用哪些COMPort。我的问题(位于define_ports()函数中)是我想知道如何根据我之前定义的电缆连接数量动态地为用户吐出输入。如果这很简单,我深......
  • 【C++基础知识——迭代器 引入】
    问题引入#include<iostream>#include<map>#include<string>intmain(){//定义一个std::map容器std::map<std::string,int>ageMap;ageMap["Alice"]=30;ageMap["Bob"]=25;ageMap["Charlie&q......
  • 代码随想录算法训练营Day13 | 递归遍历、迭代遍历、层序遍历
    目录递归遍历和迭代遍历:144.二叉树的前序遍历94.二叉树的中序遍历145.二叉树的后序遍历层序遍历:102.二叉树的层序遍历107.二叉树的层序遍历Ⅱ199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧......
  • Python&C++迭代器比较
    Python&C++迭代器比较内容在Python和C++中,迭代器的概念都有类似的作用,但它们的实现方式和细节上存在一些区别。下面我们将从迭代器的定义、特性以及Python和C++中的不同点来进行对比。1.什么是迭代器?迭代器是一种对象,它允许你遍历一个集合(如列表、字典、字符串等)中......
  • 迭代器模式:如何实现遍历数据时的职责分离?
    迭代器模式是我们学习一个设计时很少用到的、但编码实现时却经常使用到的行为型设计模式。在绝大多数编程语言中,迭代器已经成为一个基础的类库,直接用来遍历集合对象。在平时开发中,我们更多的是直接使用它,很少会从零去实现一个迭代器。今天,我们就一起来看看迭代器模式的原理和实现,帮......
  • 从数据中台到数据飞轮:持续迭代是关键
    在当今快速迭代的大数据时代,企业如何有效利用日益积累的海量数据,已成为业界普遍关注的话题。数据中台,作为企业集成和管理数据的中枢平台,为数据的存储和初步处理提供了便利。但光有数据中台,并不足以实现数据的最大价值。此时,“数据飞轮”概念的引入,被视为推动企业数据能力向更高层次......
  • C++容器list底层迭代器的实现逻辑~list相关函数模拟实现
    目录1.两个基本的结构体搭建2.实现push_back函数3.关于list现状的分析(对于我们如何实现这个迭代器很重要)3.1和string,vector的比较3.2对于list的分析3.3总结4.迭代器类的封装5.list容器里面其他函数的实现6.个人总结7.代码附录1.两个基本的结构体搭建首先就是我......
  • 迭代器可能的报错:ConcurrentModificationException(并发修改异常)注意事项
    参考:ConcurrentModificationException(并发修改异常)可能原因和解决方法Java迭代器详解,看这一篇就够了JAVAiterator迭代器遍历一遍后不能再遍历了吗迭代器循环list集合的顶层接口Collection继承Iterable接口,实现迭代器iterator()迭代器一旦定义,不允许其他地方对其定义的集合......
  • 迭代器范围构造函数
    C++中支持std::stringstr(v.begin(),v.end());这样的写法,是因为C++的STL(标准模板库)容器和字符串类都支持迭代器范围构造函数。这种写法主要涉及以下几个概念:1.迭代器范围构造函数C++标准库中的许多容器(如std::vector、std::list、std::string)都提供了一种构造函数,它允......
  • 第七章习题12-用牛顿迭代法求根。方程为一元三次函数,系数a,b,c,d的值依次为1,2,3,4,由
     ......