在阅读brettslatkin的《有效的Python》一书时,我注意到作者建议,有时使用生成器函数和对生成的迭代器调用list来构建一个列表,可以产生更干净、更可读的代码。你知道吗
举个例子:
num_list = range(100)
def num_squared_iterator(nums):
for i in nums:
yield i**2
def get_num_squared_list(nums):
l = []
for i in nums:
l.append(i**2)
return l
用户可以调用
l = list(num_squared_iterator(num_list))
或者
l = get_num_squared_list(nums)
得到同样的结果。你知道吗
建议generator函数的噪声更小,因为它更短,并且没有创建列表和向列表中附加值的额外代码。你知道吗
(请清楚地注意,对于这些简单的示例,列表理解或生成器表达式会更好,但让我们假设这是一种模式的简化,可以用于列表理解中不清楚的更复杂代码)
我的问题是,在列表中包装生成器是否需要成本?它的性能是否等同于列表构建功能?你知道吗
我可以确认带有
list
示例的生成器更快:然而,还有更多的故事。传统观点认为,生成器比迭代其他类型的iterables要慢,因此生成器的开销很大。但是,使用
list
会将列表构建代码向下推到C级,所以您看到了一种中间立场。注意,使用for循环可以优化如下:现在您看到,如果您“内联”
l.append
(这是list
构造函数所避免的),方法中的许多差异都可以得到改善。一般来说,Python中的方法解析速度很慢。在紧密循环中,上面的微优化是众所周知的,并且是使for循环更高效的第一步。你知道吗看到这一点,我决定做一个快速测试,并编写和运行以下代码:
我运行了很多次测试代码,每次(令我惊讶的是)get\u num\u squared\u list\u from\u iterator函数实际上比get\u num\u squared\u list函数运行得(稍微)快。你知道吗
以下是我头几次跑步的结果:
1。 get_num_squared_list的运行时间=5.2928924560546875e-05
从迭代器获取平方列表的运行时间=5.0067901611328125e-05
2。 get\u num\u squared\u list的运行时间=5.3882598876953125e-05
从迭代器获取平方列表的运行时间=4.982948303222656e-05
三。 get\u num\u squared\u list的运行时间=5.1975250244140625e-05
从迭代器获取平方列表的运行时间=4.76837158203125e-05
我猜这是因为做一个列表.append在循环的每次迭代中使用get\u num\u squared\u list函数。你知道吗
我觉得这很有趣,因为代码不仅清晰优雅,而且性能更高。你知道吗
相关问题 更多 >
编程相关推荐