加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

帮助需要使用List Comprehensions改进Python代码

发布时间:2020-12-20 13:04:19 所属栏目:Python 来源:网络整理
导读:我一直在家写小 Python程序来学习更多关于语言的知识.我试图理解的最新功能是List Comprehensions.我创建了一个小脚本,根据我过去换油的频率来估计我的汽车何时需要换油.在下面的代码片段中,oil_changes是我更换石油的里程数列表. # Compute a list of the m
我一直在家写小 Python程序来学习更多关于语言的知识.我试图理解的最新功能是List Comprehensions.我创建了一个小脚本,根据我过去换油的频率来估计我的汽车何时需要换油.在下面的代码片段中,oil_changes是我更换石油的里程数列表.

# Compute a list of the mileage differences between each oil change.
diffs = [j - i for i,j in zip(oil_changes[:-1],oil_changes[1:])]

# Use the average difference between oil changes to estimate the next change.
next_oil = oil_changes[-1] + sum(diffs) / len(diffs)

代码产生了正确的答案(手动数学检查)但它感觉不到Pythonic.我在第一行做了很多不必要的原始列表复制吗?我觉得有更好的方法可以做到这一点,但我不知道它是什么.

解决方法

正如其他答案所指出的那样,除非你的石油交换清单非常长,否则你不必担心.但是,作为“基于流”计算的粉丝,我认为有趣的是指出itertools提供了在O(1)空间中计算next_oil值所需的所有工具(当然还有O(N)时间!) )无论N多大,也就是len(next_oil)得到.

izip本身是不够的,因为它只会减少乘法常数,但会将空间需求留作O(N).将这些要求降低到O(1)的关键想法是将izip与tee配对 – 并且避免列表理解,无论如何都是O(N)空间,支持一个简单的老式循环! – ).来了:

it = iter(oil_changes)
  a,b = itertools.tee(it)
  b.next()
  thesum = 0
  for thelen,(i,j) in enumerate(itertools.izip(a,b)):
    thesum += j - i
  last_one = j
  next_oil = last_one + thesum / (thelen + 1)

我们不是从列表中取出切片,而是在其上取一个迭代器,发球(制作两个可独立推进的克隆),然后前进一次克隆,b. tee占空间O(x)其中x是各种克隆前进之间的最大绝对差异;在这里,两个克隆的进展最多只相差1,所以空间要求显然是O(1).

izip对两个稍微歪斜的克隆迭代器进行了一次一个“压缩”,我们将它打扮成枚举,这样我们就可以跟踪我们经历循环的次数,即我们可迭代的长度.重复迭代(我们需要在最终表达式中使用1,因为枚举从0开始! – ).我们用一个简单的=来计算总和,这对数字来说很好(总和更好,但它不会跟踪长度! – ).

在使用last_one = a.next()的循环之后很有诱惑力,但这不会起作用,因为a实际上已经耗尽了 – izip从左到右推进了它的参数迭代,所以它在它实现b结束之前最后一次前进! – ).没关系,因为Python循环变量的范围不限于循环本身 – 在循环之后,j仍然具有在izip放弃之前通过前进b提取的最后一次提取的值(就像thelen仍然具有返回的最后一个计数值)枚举).我仍然在命名值last_one而不是直接在最终表达式中使用j,因为我认为它更清晰,更具可读性.

所以它是 – 我希望它是有益的! – ) – 虽然为了解决你这次提出的具体问题,但几乎可以肯定是过度杀伤.我们意大利人有一句古老的谚语 – “Impara l’Arte,e mettila da parte!”……“学习艺术,然后把它放在一边” – 我认为这在这里非常适用:学习是件好事先进而复杂的方法来解决非常困难的问题,以防万一你遇到它们,但是对于所有你需要在简单和普通问题的更常见的情况下寻求简单和直接的方法 – 不应用最有可能赢得的高级解决方案不需要! – )

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读