delphi 控件前有加号可以展开_比较python中展开二维列表的五种方法

本文作者Chris Conlan,他写了一本书叫做Fast Python,专门分析怎么写python效率(主要是时间效率)最高。但我暂时还没找到电子版,等找到了和大家分享。

这篇文章分析了五种将二维列表平铺为一位列表的方法,并对比他们的时间效率。最后的结果显示,这五种方法的实际运行速度和Python论坛里或者人们的直观感受完全不一样。

原文链接:https://chrisconlan.com/fastest-way-to-flatten-a-list-in-python/

b997794370c44d11966f003bdb00fcc3

五种方法的代码:

# Use long-form list additiondef slow_add_flatten_lists(the_lists):    result = []    for _list in the_lists:        result = result + _list    return result # Use list addition with the += operatordef add_flatten_lists(the_lists)    result = []    for _list in the_lists:        result += _list    return result # Use List.extenddef extend_flatten_lists(the_lists):    result = []    for _list in the_lists:        result.extend(_list)    return result # Use List.appenddef append_flatten_lists(the_lists)    result = []    for _list in the_lists:        for val in _list:            result.append(val)    return result # Use a nested list comprehensiondef comprehension_flatten_lists(the_lists)    return [val for _list in the_lists for val in _list]

大多数人会认为第三种或者第五种方法会是最快的,因为它们最简洁而且最好的利用了python中已有的数据结构。但事实并非如此。

实际上,第二种方法,也就是利用 += 操作的方法明显比其他方法要快。

大多数人认为 += 会比较慢,因为 a += b 等价于 a = a + b。而直接把列表用加号加起来应该是比较慢的,所以用 += 应该也比较慢。

但并非如此。

+= 这个操作在列表中被优化过了,完全不等价于直接使用加号。更令人吃惊的是,用了 += 之后,它不仅比正常使用加号的方法快,而且还是五种方法中最快的那个。

由于原作者并没有对运行结果(下面两张图)进行分析,所以薄荷糖在这里简单分析下。

下面两张图分别展示了五种方法的运行速度,和每百万秒五种方法可以处理的数据量。两张图都是log-log图,所以实际运行时间差会比我们看到的更大一些。

我们可以明显看出,在第一张图中,使用 += 操作的方法(蓝色线)明显比其他方法更快一些。直接利用 + 展开(紫色线)确实是最慢的,而且比另外四种方法要慢许多。

49fde7ebd05a41c7a600e1113f9903fd
a80b0ab95fa744c7a19565d8ae2c92f1
b997794370c44d11966f003bdb00fcc3

作为一个好学宝宝,薄荷糖不能知其然而不知其所以然。原作者只通过实验告诉我们 += 快,但是为什么呢?

这里薄荷糖又去翻了翻源代码,想看看 += 和 + 到底有什么不同。然后发现,+= 其实是in-place operations,也就是在原本的变量之上进行修改。而 + 不是。

举个栗子。

a = a + b

这里 a 和 b 都是列表。那么当两个列表相加的时候,python会开辟另一个存储空间来存放新生成的列表。之后再把新生成的列表赋值给 a。

而使用 += 会直接把 b 加在之前的列表 a 上面,于是不需要额外的存储空间和赋值操作。 因此会快许多。

如果有说错的地方,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值