在python学习过程中查看某个函数的返回值时,蹦出了一条打印:
<generator object bigrams at 0x000001D5B9FC3AC0>
本来预期函数返回的是列表,为什么会出现这个打印呢?
查了下才知道这条打印的含义,直译为“生成器对象bigrams在0x000001D5B9FC3AC0”,也就是说函数返回的不是列表,而是一个“生成器对象”。什么是生成器对象呢 ?
原来生成器对象是一个可以产生数据,可迭代的一个对象。与此相关的还有一个“生成器表达式”概念。
1. 生成器表达式
列表推导的时候一般这么写,这里的mylist是一个列表类型:
>>> mylist = [n for n in range(10)]
>>> mylist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果把这里的"[ ]"换成"( )",就发生了一件神奇的事情,mylist不是列表类型,而是一个“生成器表达式”:
>>> mylist = (n for n in range(10))
>>> mylist
<generator object <genexpr> at 0x000001D5B9FC3A50>
这里的打印说明mylist是一个<genexpr>生成器表达式(generator expression)。突然感觉python高深莫测。
怎么查看生成器表达式的结果呢?有两种方式:
第一种用list:
>>> list(mylist)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
第二种用for循环:
>>> for n in mylist:
... print(n)
...
0
1
2
3
2. 生成器对象
函数里使用yield关键字,这个函数就会返回生成器对象。下面代码里的g就是生成器对象:
>>> def num(start, stop, increment):
... x = start
... while x < stop:
... yield x
... x += increment
...
>>> g = num(0, 10, 1)
>>> g
<generator object num at 0x000001D5B9FC3E40>
>>> list(g)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
总结:目前我能体会到的使用生成器的好处就是不用一次性产生完整的列表数据,而是通过循环每次获取下一个数据来使用,如果数据量很大的话,这可以节省内存空间。由于工作中没有用到生成器,其他的好处还体会不到。