



























前几天刷推,看到 Rich 的作者发了一条推特,这个问题相当的有趣,前几天在做 iBeats 的时候也遇到过类似的需求,手痒试试有没有好的解法。

我的解法还不错,还得到了作者的称赞,开心了一下~
推特的好处是能遇到各种有趣的解法和讨论,下面对每个解法的解释,其中不少 Python 的巧妙应用
def merge(a, b): res = [] for ab in zip(ab): res.extend(ab) return res
这种的解法的好处是清晰易懂,坏处是因为会不断的 resize list 当列表很大的时候会有效率问题
from itertools import chain chain.from_iterable(zip(a,b))
这种是比较 Pythonic 的解法,用到了 Python 标准库中非常好用的 itertools, 且不用引入中间变量,没有特别的效率问题,清晰直观,也是工作中比较推荐的代码。
以上的都有循环或需要不断 resize 的小问题,那么能不能不 resize 呢?如果列表的长度相同,是可以的,我们只需要建一个列表,然后把 a, b 的元素按规定放进去就行了,这就用到了 Python 非常强大的切片了。


可以看出,如果不去 resize 的话会有将近 10 倍的效率
def merge_gen(a, b): for thing1, thing2 in zip(a, b): yield thing1 yield thing2 list(merge_gen(a, b))
用到了生成器,还不需要引入中间变量,效率同样很高
这个解法的有趣的地方在于,sum 是有第二个参数的,作为起始,默认是 0, 如果我们把第二个参数放一个空的 tuple, 就相当于不断的迭代,求和。

但因为也是循环迭代,当大列表时候存在效率问题
从这一个问题动手研究,看大家的思路,还是非常有趣的,有些解法很巧妙也很好玩,参与其中也体会到了写 Python 的乐趣,虽然这些大部分的方式不会让我们在工作中写出更好的代码。但,研究这些方式背后的知识非常有趣,至少让我快乐了一个小时,把我的快乐分享给大家哈哈。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。