做 LeetCode 题目,1189. “气球” 的最大数量,虽然执行效率也是排在前面,但写了很大段代码,然后就发现一个简洁到极致的代码:
return unt(key) // abc for key, abc in collections.Counter(“balloon”).items())
将 unt(key) // abc for key, abc in collections.Counter(“balloon”).items() 单独打印查看类型
f = (unt(key) // abc for key, abc in collections.Counter("balloon").items())print(type(f)) #输出<generator object Solution.maxNumberOfBalloons.<locals>.<genexpr> at 0x7ffbe29cf9e0>
发现 generator 没学过啊。。于是找到一个很好的教程:
Python yield 使用浅析
注意: 这个文档是使用 Python 2 写的。改写 iterable 的 class 时,要把 next 方法改为 __next__
Iterable
:__iter__
的类,那么就认为它有迭代能力,通常此函数必须返回一个实现了__next__
的对象,如果自己实现了,你可以返回self,当然这个返回值不是必须的。Iterator (迭代器)
:__iter__
和__next__
的对象,缺少任何一个都不算是Iterator。 Iterator 当然也是 Iterable。generator(生成器)
借一张图来说明它们的关系
使用代码来展示 generator 与 Iterator,Iterable 的关系:
from inspect import isgeneratorfunctionfrom collections import Iterable, Iteratorimport typesdef fab(max):n, a, b = 0, 0, 1while n < max:yield ba, b = b, a + bn += 1# 不会执行函数体,而是返回 generator 对象 v = fab(5)print("is a generator? %s" % isinstance(v, types.GeneratorType))print("is a Iterable? %s" % isinstance(v, Iterable))print("is a Iterator? %s" % isinstance(v, Iterator))
执行结果:
is a generator? Trueis a Iterable? Trueis a Iterator? True
yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 generator 函数不会执行函数体,而是返回一个 generator 对象!
在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,
- 执行到 yield b 时,fab 就返回一个迭代值
- 下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield
- 也可以手动调用 fab(5) 的 next() 方法(因为 fab(5) 是一个 generator 对象,该对象具有 __next__() 方法),这样我们就可以更清楚地看到 fab 的执行流程:
执行 next 流程:v = fab(5)while(True):print(v.__next__())
执行结果:
11235Traceback (most recent call last):File "d:/workspace/study/python/test.py", line 10, in <module>print(v.__next__())StopIteration
本文发布于:2024-02-01 18:55:13,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170678491238744.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |