Python中神奇的迭代器和生成器

unity游戏开发日志(一)将mmd模型导入unity,并解决材质丢失的问题 unity音乐游戏开发,导入角色模型并解决材质问题 阅读详情

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入



给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

 

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

要解决这个问题,常规算法是贪心算法。我们维护两个指针指向两个字符串的开头,然后对第二个字符串一路扫过去,如果某个字符和第一个指针指的一样,那么就把第一个指针前进一步。第一个指针移出第一个序列最后一个元素的时候,返回 True,否则返回 False。

不过,这个算法正常写的话,写下来怎么也得八行左右:

def is_subsequence(s: str, t: str) -> bool:
    n, m = len(s), len(t)
    i = j = 0
    while i < n and j < m:
        if s[i] == t[j]:
            i += 1
        j += 1
    return i == n

print(is_subsequence("ace", "abcde"))
print(is_subsequence("aec", "abcde"))

但如果我们使用迭代器和生成器,代码量将大幅度减少:

def is_subsequence(s: str, t: str) -> bool:
    t = iter(t)
    return all(i in t for i in s)
 
print(is_subsequence("ace", "abcde"))
print(is_subsequence("aec", "abcde"))

而且运行结果正确与上面一样,都是:

True
False

但如果你对python的生成器运行机制不太了解,一定会看的一脸懵逼。

不过不用担心,我今天分享的主题便是python的迭代器和生成器剖析。
本文目录

  • 迭代器和可迭代对象
  • 列表生成式与列表生成器
  • 函数生成器(generator)
  • 迭代器和生成器的关系
  • 利用生成器判断子序列详解
  • 总结

迭代器和可迭代对象

在 Python 中一切皆对象,对象的抽象就是类,而对象的集合就是容器。

列表(list: [0, 1, 2]),元组(tuple: (0, 1, 2)),字典(dict: {0:0, 1:1, 2:2}),集合(set: set([0, 1, 2]))都是容器。对于容器,可以认为是多个元素在一起的单元;而不同容器的区别,正是在于内部数据结构的实现方法。

所有的容器都是可迭代对象(iterable):

from collections.abc import Iterable
params = [
    1234,
    '1234',
    [1, 2, 3, 4],
    set([1, 2, 3, 4]),
    {1: 1, 2: 2, 3: 3, 4: 4},
    (1, 2, 3, 4)
]

for param in params:
    print(f'{param}是否为可迭代对象? ', isinstance(param, Iterable))

运行结果:

1234是否为可迭代对象?  False
1234是否为可迭代对象?  True
[1, 2, 3, 4]是否为可迭代对象?  True
{1, 2, 3, 4}是否为可迭代对象?  True
{1: 1, 2: 2, 3: 3, 4: 4}是否为可迭代对象?  True
(1, 2, 3, 4)是否为可迭代对象?  True

可以看到所有的集合容器都是可迭代对象(iterable),字符串也是可迭代对象,唯有单个数字不是可迭代对象。

而可迭代对象,可以通过 iter() 函数返回一个迭代器,当然迭代器本身也属于可迭代对象:

from collections.abc import Iterable, Iterator
params = [
    '1234',
    [1, 2, 3, 4],
    set([1, 2, 3, 4]),
    {1: 1, 2: 2, 3: 3, 4: 4},
    (1, 2, 3, 4)
]

for param in params:
    param = iter(param)
    print("----------")
    print(f'{param}是否为可迭代对象? ', isinstance(param, Iterable))
    print(f'{param}是否为迭代器对象? ', isinstance(param, Iterator))

运行结果:

 

 

这意味着迭代器本身也可以获取它自己的迭代器,例如:

for i in iter(l):
    print(i, end=",")
print()
for i in iter(iter(l)):
    print(i, end=",")

运行结果:

1,2,3,4,
1,2,3,4,

迭代器(iterator)提供了一个 next的方法。调用这个方法后,你要么得到这个容器的下一个对象,要么得到一个 StopIteration 的错误:

l = [1, 2, 3, 4]
l = iter(l)
while True:
    print(l.__next__())

结果:

1
2
3
4
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-16-e106f3a7bd73> in <module>()
      2 l = iter(l)
      3 while True:
----> 4     print(l.__next__())

StopIteration: 

当然上面的l.next()应该改写成next(l),next()方法的本质就是调用目标对象的next()方法。

实际上for循环:

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

的本质等价于:

l = [1, 2, 3, 4]
l_iter = iter(l)
while True:
    try:
        i = next(l_iter)
    except StopIteration:
        break
    print(i)

for in 语句将这个过程隐式化了。

列表生成式与列表生成器

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

print([x * x for x in range(1, 11)])
print([x * x for x in range(1, 11) if x % 2 == 0])

##还可以使用两层循环,可以生成全排列:
print([m + n for m in 'ABC' for n in 'XYZ'])
print([str(x)+str(y) for x in range(1,6) for y in range(11,16)])

##for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value:
d = {'x': 'A', 'y': 'B', 'z': 'C' }
print([k + '=' + v for k, v in d.items()])

结果:


[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
['111', '112', '113', '114', '115', '211', '212', '213', '214', '215', '311', '312', '313', '314', '315', '411', '412', '413', '414', '415', '511', '512', '513', '514', '515']
['x=A', 'y=B', 'z=C']

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

只要把一个列表生成式的[]改成(),就创建了一个generator:

g = (x * x for x in range(10))

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

用一个示例,感受一下生成器相对生成式的优势,首先创建一个查看当前内存情况的方法:

import os
import psutil

## 显示当前 python 程序占用的内存大小
def show_memory_info(hint):
    pid = os.getpid()
    p = psutil.Process(pid)

    info = p.memory_full_info()
    memory = info.uss / 1024. / 1024
    print(f'{hint}内存使用: {memory} MB')

测试一下列表生成式:

def test_iterator():
    show_memory_info('initing iterator')
    list_1 = [i for i in range(100000000)]
    show_memory_info('after iterator initiated')
    print(sum(list_1))
    show_memory_info('after sum called')

%time test_iterator()

结果:

initing iterator内存使用: 48.69140625 MB
after iterator initiated内存使用: 3936.2890625 MB
4999999950000000
after sum called内存使用: 3936.29296875 MB
Wall time: 9.39 s

测试一下列表生成器:

def test_generator():
    show_memory_info('initing generator')
    list_2 = (i for i in range(100000000))
    show_memory_info('after generator initiated')
    print(sum(list_2))
    show_memory_info('after sum called')

%time test_generator()

结果:

initing generator内存使用: 48.8515625 MB
after generator initiated内存使用: 48.85546875 MB
4999999950000000
after sum called内存使用: 49.11328125 MB
Wall time: 7.95 s

声明一个迭代器很简单,[i for i in range(100000000)]就可以生成一个包含一亿元素的列表。每个元素在生成后都会保存到内存中,你通过上面的代码可以看到,它们占用了巨量的内存,内存不够的话就会出现 OOM 错误。

不过,我们并不需要在内存中同时保存这么多东西,比如对元素求和,我们只需要知道每个元素在相加的那一刻是多少就行了,用完就可以扔掉了。

函数生成器(generator)

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契数列用列表生成式写不出来,但是用函数把它打印出来却很容易:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1

fib(6)

打印结果:

1
1
2
3
5
8

上面的函数和生成器(generator)仅一步之遥,只要把print(b)改为yield b,fib函数就会变成生成器(generator):

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

这就是除了列表生成器以外定义generator的另一种方法。

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

fib(6)

结果:

<generator object fib at 0x0000000005F04A98>

在前面的列表生成器中我已经讲过,对于生成器可以使用for循环进行遍历:

for i in fib(6):
    print(i)

打印结果:

1
1
2
3
5
8

这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

举个简单的例子,定义一个generator,依次返回数字1,3,5:

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:

o = odd()
while True:
    print(next(o))

结果:

step 1
1
step 2
3
step 3
5
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-7-554c5fb505f8> in <module>()
      1 o = odd()
      2 while True:
----> 3     print(next(o))

StopIteration: 

可以看到,odd不是普通函数,而是generator,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next()就抛出StopIteration异常。

对于函数生成器(generator)来说,遇到return语句就是结束generator的指令(函数体最后一行语句其实隐式执行了return None),for循环随之结束。

迭代器和生成器的关系

其实生成器就是一种特殊的迭代器,而迭代器包括了生成器并不等价于生成器,它们都可以通过next()方法不断的获取下一个对象,都具备记忆已经读取的位置的特点。

例如:

l = [1, 2, 3, 4]
l_iter = iter(l)

完成可以理解为产生了一个列表生成器:

l = [1, 2, 3, 4]
l_iter = (i for i in l)

也可以理解成产生了一个函数生成器:

l = [1, 2, 3, 4]

def func_generator(l):
    for i in l:
        yield i

l_iter = func_generator(l)

利用生成器判断子序列详解

有了前面的基础知识,相信文章开头的代码还稍微有点眉目了。现在我们再回到文章开头的代码,详细分析一下:

def is_subsequence(s: str, t: str) -> bool:
    t = iter(t)
    return all(i in t for i in s)
 
print(is_subsequence("ace", "abcde"))
print(is_subsequence("aec", "abcde"))

首先t = iter(t)我们可以理解为产生了一个生成器:

t = (i for i in t)

而i in t基本上等价于:

while True:
    val = next(t)
    if val == i:
        yield True

测试一下:

t = "abcde"
t = (i for i in t)
print('a' in t)
print('c' in t)
print(next(t))

结果:

True
True
d

可以看到最后一行直接返回了匹配到c的下一个值'd'。

这样我们再测试:

t = "abcde"
t = (i for i in t)
print('a' in t)
print('c' in t)
print('b' in t)

结果:

True
True
False

于是就可以顺利的使用生成器计算子序列的每个元素是否满足条件:

t = iter("abcde")
[i in t for i in "aec"]

结果:

[True, True, False]

而all()函数即可判断是否全部都满足条件:

print(all([True, True, False]), all([True, True, True]))

结果:

False True

而上述代码all(i in t for i in s)没有申明all([i in t for i in s])列表生成式形式则代表是对一个列表生成器进行all运算。

总结

于是到此,我们就很优雅地解决了这道题。不过一定要注意,实际工作中尽量不要用这种技巧,因为你的领导和同事有可能并不知道生成器的用法,你即使写了详细的注释他们也难以理解,不如用常规方法解决比较好!经过今天的学习,希望你已经在生成器这个技术知识点上比其他人更加熟练了。

今天本文分享了容器、可迭代对象、迭代器和生成器四种不同的对象:

  • 容器是可迭代对象,可迭代对象调用 iter() 函数可以得到一个迭代器。
  • 迭代器可以通过 next() 函数来得到下一个元素,从而支持遍历。
  • 生成器是一种特殊的迭代器(迭代器却不见得是生成器)。
JAVA:Spring Boot3 集成 ShardingSphere 实现数据分库分表 本文介绍了基于Spring Boot和ShardingSphere-JDBC实现分库分表与读写分离的解决方案。针对高并发、大数据量场景下单库单表的性能瓶颈,通过配置ShardingSphere-JDBC实现:1)订单表按user_id和order_id分片到两个库和两张表;2)读写分离,写操作路由至主库,读操作在从库间负载均衡。方案使用Druid连接池优化,支持业务透明,无需修改SQL。 阅读详情

相关推荐

别再手动对照了!用Python+ArcGIS Pro一键搞定三调数据转土地三大类

本文介绍如何利用Python和ArcGIS Pro实现三调数据向土地三大类的自动化转换,大幅提升国土空间规划和土地变更调查的工作效率。通过封装分类规则为Python函数并集成到ArcGIS Pro脚本工具中,解决了传统手动操作耗时且易错的问题,适用于大规模数据处理场景。

weixin_29081101的博客 307

深度学习经典优化方法实现

目录 前言 一、梯度下降 二、随机梯度下降 三、小批量梯度下降 四、Adam算法 总结 前言 参考邱锡鹏老师的《神经网络与深度学习》(俗称蒲公英书),记录一下笔记. 一、梯度下降 def bgd(params,lr): for param in params: param.data -= lr*param.grad/1000 二、随机梯度下降 每次迭代只从训练集中取出一个样本更新梯度 def sgd(params,lr): ...

qq_43432826的博客 1472

UE4_后期处理六—夜视仪、扫描线

观察下面一组蓝图节点的效果:当把角色的自定义深度通道开启:画面效果如图:这样我们就得到了一个这样的黑白蒙版。

Growthofnotes的博客 1734

Python的迭代器和生成器

作者:小小明 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/is-subsequence 要解决这个问题,常规算法是贪心算法。我们维护两个指针指向两个字符串的开头,然后对第二个字符串一路扫过去,如果某个字符和第一个指针指的.

小小明-代码实体的专栏 3万+

Cadence Allegro通过手工绘制板框的方法

Cadence Allegro通过手工绘制板框的方法 Cadence Allegro绘制板框有三个方法: 1、通过手工绘制板框; 2、通过向导绘制板框; 3、通过导入DXF文件导绘制板框; 本章将教会大家如何通过手工的方法绘制100mm的矩形板框。 方法步骤如下: 一、通过放置绘图工具2D线绘制; 1、运行Cadence Allegro软件,打开File菜单栏,选择New。 2、这时软件会弹出Ne...

LGCPCB的博客 2万+

保姆级教程:在SIwave 2024 R2中搞定TDR仿真,手把手教你分析USB 3.0差分线阻抗

本文提供了一份详细的SIwave 2024 R2 TDR仿真教程,重点讲解如何分析USB 3.0差分线阻抗。从项目准备、参数配置到结果分析,逐步指导工程师完成完整的仿真流程,并分享实战经验和高级技巧,帮助提升信号完整性分析能力。

weixin_33670786的博客 498

LeetCode 392. 判断子序列(Is Subsequence)

LeetCode.jpg 392. 判断子序列 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcd...

墨1024 442

四足机器人跨楼层轨迹规划:SCAN-Planner-Pure-ROS2开源项目实践指南

在机器人导航领域,路径规划是让机器人从起点安全、高效移动到目标点的核心技术。其原理通常基于环境地图(如占据栅格地图或八叉树地图),通过搜索算法(如A*、RRT*)在配置空间中找到一条无碰撞的可行路径。这项技术的价值在于赋予机器人在复杂、非结构化环境中的自主移动能力,是巡检、救援、物流等应用场景的基石。对于四足机器人而言,其运动能力超越了轮式平台,能在楼梯、斜坡等三维地形中移动,这使得传统的二维规划不再适用,需要专门的三维轨迹规划算法。SCAN-Planner-Pure-ROS2正是这样一个专注于解决四足机器

weixin_30700977的博客 467

面试常问的迭代器和生成器,咱们来剥个 “洋葱“

在第一次接触 Python 的时候,你可能写过类似 for i in [2, 3, 5, 7, 11, 13]: print(i) 这样的语句。for in 语句理解起来很直观形象,比起 C++ 和 Java 早期的 for (int i = 0; i < n; i ++) printf("%d\n", a[i]) 这样的语句,不知道简洁清晰到哪里去了。 但是,你想过 Python 在处理 for in 语句的时候,具体发生了什么吗?什么样的对象可以被 for in 来枚举呢? 深入到 Pytho

软件测试前沿技术分享 480

【RT-DETR涨点改进】全网独家创新、细节涨点改进篇 | AAAI 2025 | 将 CEM 颜色增强模块引入RT-DETR ,目标检测不再惧怕雾天和低光检测、小目标检测、遥感目标检测高效涨点

本文提出了一种新型结构引导去雾网络(SGDN),通过双色引导桥(BGB)和色彩增强模块(CEM)有效解决雾霾图像去雾问题。BGB利用YCbCr空间的纹理特征引导RGB特征恢复,CEM通过聚合YCbCr通道信息增强RGB色彩感知。实验证明该方法在真实雾霾数据集上优于现有技术,能同时保持色彩准确性和纹理清晰度。文章还提供了完整的代码实现和模型配置指南,包括三种改进版RT-DETR网络结构(rtdetr-l/r18/r50-CEM.yaml),为图像去雾和目标检测任务提供了实用解决方案。

Ai缝合怪、助力小伙伴高效发论文 351

零基础DSP实战TMS320F28035:第九节,ADC比较器&EPWM

ADC比较器框图如下所示:-电压-----------------------------输出-电压A>电压B------------------ 1-电压A

sinat_30943509的博客 2536

深度学习常用语句for param in params问题:为什么修改param之后,params对应元素也随之改变?

上述代码中,param遍历params的所有元素,并进行sgd梯度下降,但是其仅仅对param进行修改,为何params元素会随之改变?于是我进行实验,发现无论是最简单的数组还是np.array(ndarray格式),都是只修改了param而不修改params,如下图所示:于是询问copilot:然而为何源码中的params会改变?

qq_22471349的博客 803

14、利用Helm和GitOps实现Kubernetes资源管理与CI/CD流程优化

本文介绍了如何结合Helm、GitOps和Terraform等工具,优化Kubernetes资源管理和CI/CD流程。内容涵盖了Helm提供程序的配置、GitOps的核心理念、CI/CD管道的构建与测试策略、GitHub源代码管理模型以及流程优化建议,旨在提升软件开发和部署的效率与质量。

y7z8a9的博客 156

Python编程的神奇工具:迭代器与生成器

在Python世界中,我们有很多强大的工具可以帮助我们更好的处理数据和解决问题,其中有2个特别引人注目,那就是迭代器和生成器。

weixin_46253270的博客 253

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Python黑魔法:探秘生成器和迭代器的神奇力量

迭代器是一种特殊的对象,它可以遍历一个集合中的所有元素。任何实现了__iter__()和__next__()方法的对象都可以被称为迭代器。首先,让我们通过一个简单的例子来看看如何创建一个迭代器: 在这个例子中,我们创建了一个迭代器,它可以逐个返回给定字符串中的所有字符。当我们试图获取下一个元素时,如果还有元素可供返回,就返回该元素,否则就抛出StopIteration异常。Python中有许多内置的迭代器,如列表迭代器、字典迭代器、文件迭代器等。下面是一些例子: 二、生成器 生成器是一种特殊的迭代器,它更加

子午的博客 253

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

python 三个内置装饰器,[Python]三个神奇的工具生成器、迭代器和装饰器,python,三大,神器...

1. 生成器squares = [i**2 for i in range(10000)]for i in squares:pass把所有元素都存在列表里,占用了大量内存,而实际上每次只用到列表中的一个元素。生成器:1.惰性计算2.边执行边计算,无需一次性存入大量数据3.实际上一直在执行next(操作),直到无值可取1.1 生成器表达式 (…)圆括号squares = (i**2 for i in ...

weixin_39926014的博客 180

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

python迭代器和生成器

迭代器(Iterator) 迭代的概念 在python中,通过for循环来逐个获取可迭代对象的每一项的过程就称为迭代(Iteration)。 #简单的迭代: for i in [1,2,3]: print(i) #1 #2 #3 可迭代对象 可以直接作用于for循环的对象统称为可迭代对象(Iterable)。 有以下几种: 集合数据类型,如list、tuple、dict、s...

Trophy's Blog 1536

python中迭代器和生成器_python 中的迭代器和生成器详解

迭代器学习过python的童鞋都应该知道python中有三大神器,即 迭代器、生成器和装饰器,所谓神器,必有其神奇之处,今天和大家一起学习一下迭代器和生成器。迭代是python比较强大的功能之一,说起迭代,我们可能会想到,对于一个列表list,一个元组tuple,访问的时候都可以使用 for .. in .. ,没错,这就是迭代,它是访问集合元素的一种方式,在从头到尾遍历可迭代对象时,能够记住遍历...

weixin_39575007的博客 128

白话Python迭代器与生成器

迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象,简单的说,就是他只记录数据在内存中所在的位置,使用的是栈的逻辑记录数据所在的内存地址,因为用的是栈的逻辑,所以只需要记住栈的起始地址,以及栈的偏移量就可以得到所有数据的内存地址。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。因此,迭代器可以存储很多数据,而不占用很多内存空间,但是这个特性也导致它无法反复读数据,也就是“阅完即焚”。 迭代器有两个基

魔都子沐的博客 324

Python 的可迭代对象、迭代器和生成器

由for循环的内部原理说起 list01 = [2,434,5,6,8] for item in list01: print(item) 大家有没有想过list类型对象为什么可以被for循环呢? 能够被for循环的条件是:它是可迭代对象(即具有__iter__()方法的对象) for循环原理 获取迭代器对象 循环迭代(调用迭代器的__next__方法) for循环内部会捕获St...

ACBC12345的博客 461

python中迭代器和生成器_Python中的迭代器和生成器

前言面试的时候总是被问到迭代器、生成器、装饰器,一开始不知道怎么回答,然后查阅资料之后总算是有点认识了。迭代器迭代器其实是一个实现了迭代器协议的容器对象。它基于2个方法:__next__: 返回容器的下一个元素__iter__: 返回迭代器本身range()函数就是一个迭代器接下来我模拟range写一个迭代器class Range:def __init__(self, start : int = ...

weixin_39895486的博客 88

Python的那些事第十三篇:迭代器、生成器、装饰器与上下文管理器的奇妙之旅

生成器就像是一个懒惰的魔法师,它不会一次性把所有的魔法都施展出来,而是等到你真正需要的时候,才给你一点点地施展。生成器是一种特殊的迭代器,它使用yield关键字来返回数据。实例:生成器的定义与使用# 定义一个生成器函数yield "魔法一:隐身术"yield "魔法二:飞行术"yield "魔法三:变身术"# 调用生成器函数# 使用 next() 方法获取魔法print(next(magic_generator)) # 输出:魔法一:隐身术。

weixin_74149145的博客 1600

6个Python迭代器及生成器酷炫实例

大家好,今天我们要一起探索Python中的六个神奇工具:迭代器和生成器。它们就像魔法棒,能让我们优雅地处理大量数据,既节省内存又高效。别担心,我会用最接地气的语言和简单易懂的代码示例来带你一探究竟!记住,学习编程就像在探索未知的世界,慢慢来,一步一步,你也会成为Python江湖的大侠!它会一步步生成0到9的数字,就像打开一个无限的巧克力盒子,每次只给你一颗。这就是个神奇的“魔术师”,每次给你递增的斐波那契数,永远不会让你等太久。集合迭代器就像从一堆随机摆放的数字中找出唯一的一样。

wenjie20070212的博客 362

迭代器与生成器

迭代器与生成器 迭代器 1.可迭代对象   对于迭代器来说,我们更熟悉的应该是可迭代对象,之前无论是源码还是讲课中或多或少我们提到过可迭代对象这个词。之前为了便于大家理解可迭代对象,可能解释的不是很正确,所以今天我们正式的聊一聊什么是可迭代对象。从字面意思来说,我们先对其进行拆解:什么是对象?Python中一切皆对象,之前我们讲过的一个变量,一个列表,一个字符串,文件句柄,函数名等等都可...

248

MacOS 上 SQLite-Vec 扩展加载报 dlopen 错?这 2 处改完就能跑

```bash $ python3 demo.py sqlite3.OperationalError: dlopen(/path/to/dist/vec0.dylib, 0x0002): invalid dylib $ sqlite3 sqlite> .load ./vec0.dylib Parse error near line 2: unable to open library "./ve

gitblog_00729的博客 636

python中的迭代器和生成器

python 迭代器和生成器

LOVE_jianshen的博客 174
上一篇: Python装饰器的六种写法
下一篇: 你所不知道的Python的精髓
酸菜鱼编程
博客等级 码龄6年 155粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值