我有一个相对较长(20, 000行)的CSV文件, 并且编写了一个简单的函数来打开它:
def read_prices():
with open('sp500.csv', 'r') as f:
reader = csv.DictReader(f)
for row in reader:
yield float(row['Adj Close'].strip())
当我按原样计时时, 它需要3e-05s:
print(timeit.timeit(lambda: read_prices('SP500.csv'), number=100))
当我使用相同的函数但使用tuple(… )时, 它要花费高达27秒的时间:
print(timeit.timeit(lambda: tuple(read_prices('SP500.csv')), number=100))
这对tuple()正常吗?为什么会这样呢?我是一个初学者, 所以欢迎使用ELI5解释:)
#1发生这种情况是因为read_prices不是函数-实际上是生成器。那是因为yield关键字。
如功能编程HOWTO中所述:
任何包含yield关键字的函数都是生成器函数;这是由Python的字节码编译器检测到的, 该编译器因此专门编译了该函数。调用生成器函数时, 它不会返回单个值;而是返回一个支持迭代器协议的生成器对象。因此, 当你运行第一个read_prices(‘ SP500.csv’ )时, 会发生什么, 只是创建生成器对象, 等待被告知产生元素。
在第二个版本tuple(read_prices(‘ SP500.csv’ ))中, 你像以前一样创建了生成器对象, 但是tuple()实际上耗尽了它并立即产生了所有元素。
【tuple()增加运行时间这么多是否正常()】一个简单的演示:
>
>
>
def yielder():
...yield from [1, 2, 3]
...
>
>
>
y = yielder()
>
>
>
y
<
generator object yielder at 0x2b5604090de0>
>
>
>
next(y)
1
>
>
>
list(y)
[2, 3]
>
>
>
tuple(yielder())
(1, 2, 3)
#2这是因为这是一个生成器read_prices(‘ SP500.csv’ ), 当这样调用时, 它几乎什么也不做。
但是, 当你执行此元组(read_prices(‘ SP500.csv’ ))时, 它将操作生成器并提供值。
生成器是可迭代的, 其作用是:
- for循环
- 下一个
- 使用元组(如你所述)打开包装或列出
这是生成器的一个更具体的示例:
def f():
print("First value:")
yield "first"
print("Second value:")
yield "second"
它在起作用:
### Nothing prints when called (analogous to your first timeitwithout tuple)In [2]: v = f()In [3]:### However when I call `next` the first value is provided:In [3]: next(v)
First value:
Out[3]: 'first'## etc, until there is no more values and a "StopIteration` exception is raised:In [4]: next(v)
Second value:
Out[4]: 'second'In [5]: next(v)
------------------------------------
...StopIteration:## by unpacking using "tuple" the "StopIteration"
## exception is handled and all the values are provided at once
##(like your timeit using the tuple):In [6]: tuple(f())
First value:
Second value:
Out[6]: ('first', 'second')
推荐阅读
- 如何从JSON中提取嵌套的值()
- 使用JMESPath根据另一个查询结果过滤列表
- Python Pandas ffill if语句问题()
- Pip已自行卸载,但我不知道是什么原因造成的
- 通过Python转义HTML中的单引号()
- Python中的Altair(数据可视化)
- 2020年11个最佳iOS开发框架热门推荐
- 如何实现android的翻转动画(已添加GIF)
- 安装新版本后,Android应用已关闭