目录

一、可迭代对象

1.1 判断是否为可迭代对象

二、迭代器

2.1 判断对象是否是一个迭代器

2.2 手写一个迭代器

2.3 迭代器应用场景

三、生成器

3.1 生成器介绍

3.2 使用yield 关键字 生成器,来实现迭代器

3.3 生成器(yield关键字)的运行逻辑


一、可迭代对象

可迭代对象,就是 可以使用for 循环遍历的对象。

比如 list 列表

tuple 元组

set 集合

str 字符串

dic 字典

如果想要使用for来遍历,这个对象必需具有 __iter__ 方法

1.1 判断是否为可迭代对象

方法一:

from typing import Iterable
isinstance(obj,Iterable)

方法二:

是否有__iter__ 方法

print(hasattr(list,"__iter__"))
print(hasattr(str,"__iter__"))
print(hasattr(tuple,"__iter__"))
print(hasattr(dict,"__iter__"))
print(hasattr(set,"__iter__"))True
True
True
True
True

二、迭代器

1、迭代器首先是一个可迭代对象,拥有__iter__ 方法,返回self

2、还必须要有 __next__ 方法。__next__ 方法 用来输出下一个元素。如果没有下一个值,则抛出StopIterator 异常

3、迭代器,使用for操作时,得到的每一个元素,会自动的调用__next__方法,从而得到下一个元素,依次循环,这样就能遍历所有的元素了。for语句迭代会忽略异常。

4、迭代器迭代的时候,使用for,不要使用while

5、迭代器只能迭代一次。(因为对象里用于迭代计算的下标一直是增加的)

6、迭代器比list占用更小的内存。

2.1 判断对象是否是一个迭代器

迭代器同时拥有 __iter__ 方法 与 __next__ 方法。

方法一:

isinstance(obj,Iterator)

注意,这里是Iterator 不是Iterable

列表list,是一个可迭代对象,但不是一个迭代器。

from typing import Iterable, Iteratora = [1,2,3]
print(isinstance(a,Iterable))
# True
print(isinstance(a,Iterator))
# False

将 可迭代对象,转化为一个迭代器,使用iter方法.

from typing import Iterable, Iteratora = [1,2,3]
print(isinstance(a,Iterable))
print(isinstance(a,Iterator))b = iter(a)
print(isinstance(b,Iterator))# True

2.2 手写一个迭代器

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2023 - 02 -18
# @File: my_iterator.pyclass MyIterator(object):def __init__(self, stop: int, start=0):self.stop = stopself.value = startdef __next__(self):"""返回下一个元素,没有则抛出StopIteration 异常"""if self.value < self.stop:self.value += 1else:raise StopIterationreturn self.valuedef __iter__(self):return selfif __name__ == '__main__':myIterator = MyIterator(5)print(myIterator.__next__())print(myIterator.__next__())print(myIterator.__next__())print(myIterator.__next__())print(myIterator.__next__())print(myIterator.__next__())

输出结果:

1
2
3
4
5
Traceback (most recent call last):File "/Users/zhaohui/PycharmProjects/MyTest/cekai/my_iterator.py", line 27, in <module>print(myIterator.__next__())File "/Users/zhaohui/PycharmProjects/MyTest/cekai/my_iterator.py", line 16, in __next__raise StopIteration
StopIteration

使用for遍历

    myIterator = MyIterator(5)for i in myIterator:print(i)打印结果:
1
2
3
4
5

2.3 迭代器应用场景

迭代器,占用内存,远远小于list。

需要节省内存的场景。

三、生成器

3.1 生成器介绍

生成器:为了快速、方便的创建一个迭代器。

生成器,就是一个使用了yield 关键字的迭代器。

3.2 使用yield 关键字 生成器,来实现迭代器

举例:

list = [ 1,2,3,4,5]

每个元素平方,再生成一个新的list

new_list = [1,4,9,16,25]

方法一:

使用list实现

list = [1, 2, 3]
list1 = []for i in list:list1.append(i * i)
print(list1)

方法二:

手动创建一个迭代器


class Square(object):def __init__(self, start, stop):self.value = startself.stop = stopdef __iter__(self):return selfdef __next__(self):if self.value > self.stop:raise StopIterationqueare_num = self.value * self.valueself.value += 1return queare_numif __name__ == '__main__':square = Square(1, 5)for i,s in enumerate(square):print(i,s)

打印结果:

0 1
1 4
2 9
3 16
4 25

方法三 使用yield 关键字,实现一个生成器


def square_yield(start:int,stop:int):for i in range(start,stop+1):yield i*iif __name__ == '__main__':square_yield(1,4)

yield 就等价于迭代器中的 __next__ 方法

yield 关键字,与 return 方法比较


def square_yield(start:int,stop:int):for i in range(start,stop+1):yield i*idef squqre_return(start,stop):for i in range(start,stop+1):return i*iif __name__ == '__main__':square_yield(1,4)print(squqre_return(1,4))

方法中,return 方法,就表示这个函数结束了。

yield 返回的是一个 生成器类。

3.3 生成器(yield关键字)的运行逻辑

1、yield 关键字,与return 一样,会返回一个结果。 但是return返回的是 运行结果

但是yield返回的,可不是运行结果,返回的是一个迭代器的对象。只有这个对象调用__next__

的时候,才会执行业务逻辑

2、 yield 会记录每次的运行位置。

3、只有生成器的对象在调用__next__方法时,才会执行业务代码。业务代码执行完,函数就会变成非runnning状态(挂起状态)。直到下一次__next__方法被调用

举几个例子,方便我们理解一下

举例一:

------没有使用yield关键字

def f1():print("开始执行")return "f1被执行了"if __name__ == '__main__':fun = f1()

当调用f1函数时,f1里面的业务代码被执行了。

------使用yield关键字

def f():print("yield 1------------")a = 1yield aprint("yield 2=================")a = 2yield aprint("yield 3=================")a = 3yield aif __name__ == '__main__':generator = f()

运行结果为空,因为generator = f(),得到的是一个生成器的对象,没有调用业务代码。

当我们第一次调用__next__时

    generator = f()print(generator.__next__())

输出结果:

yield 1------------
1

当第二次调用__next__时

输出结果:

yield 2=================
2

当第三次调用__next__时

输出结果:

yield 3=================
3

当生成器的对象,调用__next__方法时,yield 会记录每一次 运行的位置,当 下一次调用__next__方法时,业务代码会接着上一次的位置继续运行。

如下图:

整体代码:

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2023 - 02 -18
# @File: diedai5.pydef f():print("yield 1------------")a = 1yield aprint("yield 2=================")a = 2yield aprint("yield 3=================")a = 3yield aif __name__ == '__main__':generator = f()print(generator.__next__())print(generator.__next__())print(generator.__next__())

举例二:

解释一下上面求平方的函数,的生成器

def square_yield(start:int,stop:int):for i in range(start,stop+1):yield i*i

每次__next__ 都会记录 业务代码运行位置。

--------当第一次调用__next__ 时:

i = 1 ,返回 1x1 的结果。内存中记录 i = 1

--------第二次调用__next__ 时:

上一次的记录是i=1,开启for下一轮的循环,则i=2.返回 2x2 的结果。内存中记录 i = 2

python 迭代器生成器相关推荐

  1. python迭代器生成器 学会再缩短一半开发效率 看看大牛是怎么写的

    一.迭代 什么叫做迭代? 比如在 Java 中,我们通过 List 集合的下标来遍历 List 集合中的元素,在 Python 中,给定一个 list 或 tuple,我们可以通过 for 循环来遍历 ...

  2. python 迭代器 生成器_Python迭代器和生成器

    迭代器认知 迭代器 (iterator): 如果一个对象同时有__iter__()和__next__()魔术方法的话,这个对象就可以称为是迭代器. __iter__()的作用是可以让for循环遍历.而 ...

  3. python迭代器生成器装饰器

    基本概念 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895 817 687有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! 1.容器 ...

  4. python 生成器装饰器_4.python迭代器生成器装饰器

    基本概念 1.容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元 ...

  5. python 迭代器 生成器_python 迭代器与生成器

    迭代器 迭代器就是iter(可迭代对象函数)返回的对象,说人话.......可迭代对象由一个个迭代器组成 可以用next()函数获取可迭代对象的数据 迭代是访问集合元素的一种方式(因为集合是无序的,所 ...

  6. python 迭代器 生成器

    1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 1.1 使用迭代 ...

  7. python 生成器装饰器_七.python迭代器生成器装饰器

    1.迭代器 1.1 什么是可迭代对象(Iterable)? 定义:可以直接作用于for循环的对象统称为可迭代对象,即Iterable. 可迭代对象包括: 1.集合数据类型:如list.tuple.di ...

  8. python迭代器生成器使用技巧(2):切片、遍历、索引值、多序列、多容器对象

    1. 迭代器切片 迭代器和生成器不能使用标准的切片操作,因为它们的长度事先并不知道(并且也没有实现索引). 函数 islice() 返回一个可以生成指定元素的迭代器,通过遍历并丢弃直到切片开始索引位置 ...

  9. python迭代器生成器使用技巧(1):遍历、代理、生成器创建迭代、反向迭代

    1. 手动遍历迭代器 next() 遍历一个可迭代对象中的所有元素,但是却不想使用for循环.为了手动的遍历可迭代对象,使用 next() 函数并在代码中捕获 StopIteration 异常. 通常 ...

最新文章

  1. 自动驾驶出行,进入下半场
  2. 如何注册iClap账号?
  3. eclipse if代码折叠_仅需一页Java代码就能实现网页源码爬取
  4. Java线程详解(13)-锁
  5. OpenGL中的Shader
  6. nginx做正向代理http,内网主机yum安装外网资源
  7. 16 张图解带你掌握一致性哈希算法
  8. SAP License:合理的机制才能让系统效率最大
  9. MaxScale中间件部署数据库读写分离
  10. ping,python实现批量ping包工具--小案例v5阶段版本,可以使用了
  11. tomcat与java的版本_Tomcat JVM版本与JAVA_HOME不同
  12. YYKit源码学习——YYMemoryCache
  13. 分享超高清多机位现场直播间搭建方案
  14. 联想昭阳K22-80机器关闭或开启触摸板方法
  15. 2021.11_Coggle组队学习_Linux命令
  16. Windows Azure Active Directory (1) 前言 - 基于声明的验证和授权
  17. 大一下学期计算机基础,计算机基础复习(大一)
  18. DIY树莓派小车(一)树莓派4B+TB6612FNG驱动直流电机
  19. python的全局静态变量
  20. 坐标系统的详解-gis

热门文章

  1. 摩托罗拉 moto X30 冠军版值得买吗 配置怎么样
  2. Table表格字段居中,跨行跨列
  3. 【面经】阿里前端社招面试总结
  4. 计算机视觉:卷积神经网络在计算机视觉领域大放异彩的原因
  5. C++跳出for循环的方式
  6. python实现图书管理系统(超详细)
  7. 初试微信开发--验证token
  8. uniapp分享微信 朋友圈 微博 qq
  9. html文件中img的路径
  10. 网络安全——一图看懂HTTPS建立过程