Python 生成器的问题

2021-07-02 10:40:52 +08:00
 woshichuanqilz

学习 python 生成器的时候遇到一个问题, 生成器的目的是减少空间占用, 所以每次只是返回一个值. 再有通项公式的时候我能理解, 每一项实际上都可以算出来这样就不用记录全部的元素了. 但是如果我随便找一个没有规律的 list 做成生成器, 那么空间的节约体现在哪里呢? 比如我有这样的代码

(x for x in [1,5,-1,10])

假设我的这个 list 是没有规律的, 那么这个生成器是不是要存下来整个的 list, 那么空间的节约体现在哪里?

2378 次点击
所在节点    Python
14 条回复
HashV2
2021-07-02 10:44:29 +08:00
你内存里都已经有 list 了,为什么还要用生成器去遍历,直接遍历你的 list 不就好了

想省内存,就想办法把你最开始那个 list 写成生成器
yufpga
2021-07-02 10:53:14 +08:00
首先生成器的目的并不是为了减少空间占用。其次你要搞明白生成器的原理, 就绕不开理解 yield 的机制。(x for x in [1,5,-1,10]) 等价于:

def gen():
for i in [1, 5, -1, 10]:
yield i

g = gen()
wuwukai007
2021-07-02 10:54:48 +08:00
@yufpga 你这个也占用内存得啊。
est
2021-07-02 10:57:05 +08:00
mylist = [1,5,-1,10]
(x*2 for x in mylist)
(x/2 for x in mylist)


这这种就节约空间了。不用存 3 份。
HashV2
2021-07-02 10:59:12 +08:00
@yufpga #2 这种惰性的迭代器不就是为了减少内存占用的么? 不为这个的话是为了什么啊
yufpga
2021-07-02 11:08:52 +08:00
@wuwukai007
@HashV2
我并没有在解释节省内存的问题,我在说的是生成器的原理,解释元祖形式的列表生成器的本质。

可以去看看 python 生成器的 PEP ( https://www.python.org/dev/peps/pep-0255/), 该有的里面都有.

事实上,你们也看到,生成器不一定总是会减少内存占用
yufpga
2021-07-02 11:12:23 +08:00
@HashV2 你说的惰性迭代器缺失可以减少内存占用,但生成器的应用场景不只是迭代器上
HashV2
2021-07-02 11:17:38 +08:00
@yufpga #7 👌
abersheeran
2021-07-02 12:22:20 +08:00
你的场景不对。

比如你要处理一个 31Gb 的文件,你电脑却只有 16G 内存,该怎么办呢?这时候用 yield file.read(4096) 进行流式处理。就能大幅度节约内存空间。
BeautifulSoap
2021-07-02 12:36:39 +08:00
谈生成器不谈迭代器的话你当然搞不清楚这么搞是为什么

生成器的一个目的是方便遍历啊,一些情况下的确可以省内存,但是重点是方便遍历啊,方便遍历啊(重要的说三遍

迭代器通过统一了__next__()和__iter__()两个接口,可以让使用者不用在乎你内部结构多么复杂,你只要用 iter()和 next()这两个方法都可以轻松遍历。并且学过迭代器的人难道忘了么,你一直习以为常在用的 `for i in xxxx` 这写法实际上就是个语法糖 iter()和 next()写法的语法糖啊。省内存只不过是迭代器带来的优点之一,根本目的还是统一了接口可以让你轻松遍历对象


然后就是生成器,生成器可以部分看作是迭代器的语法糖(虽然 yield 作用不止是语法糖),你手写迭代器需要实现__next__()和__iter__()两个接口,而用 yield 构建的生成器只需要简单几行代码就行了,生成器和迭代器一样可以使用 next()迭代,也能用 `for in xxx` 这个语法糖,所以,本质上还是为了方便遍历啊
Lemeng
2021-07-02 12:46:19 +08:00
路过,学习一下
deplives
2021-07-02 13:45:19 +08:00
因为当你如果有一个几百 G 文件需要遍历而你的内存只有 512M,你就知道他是干啥的
ipwx
2021-07-04 22:24:48 +08:00
那如果你 [1, 5, -1, 10] 是从文件读出来的呢。。。? 你可以每次只读 100 个,但是返回一个丢出去。多好
shendun
2021-07-04 22:29:02 +08:00
@ipwx 大佬求联系方式 聊几句可以吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/787076

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX