【问题标题】:List of growing sum as a one-liner possible?单行可能的增长总和列表?
【发布时间】:2014-02-26 10:46:58
【问题描述】:

我想总结一个可迭代的整数,并为每个元素生成不断增长的总和。这是使用迭代编程的简单事情:

def growingSum(elements):
  sum = 0
  for element in elements:
    sum += element
    yield sum

但它是否可以在不使用变量的情况下以函数方式完成,所以可能是使用推导式的单行代码?

【问题讨论】:

  • itertools.accumulate()... 但我担心这是重复的。
  • 不,更多的是关于核心语言及其可能性的问题。通过在问题中提出一个实现,我想我展示了对迭代解决方案的认识,该解决方案也在accumulate() 中实现。这仅指实现不符合我的条件的解决方案的库。

标签: python functional-programming generator list-comprehension


【解决方案1】:

在 Python3.2+ 上你可以使用itertools.accumulate:

>>> from itertools import accumulate
>>> list(accumulate(range(10)))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

【讨论】:

  • accumulate() 的实现不符合我的条件,但是感谢那个指针。如果我不想写我的问题中的五行,我会用它来代替;-) 但我的问题确实更多的是学术层面的。
【解决方案2】:

从技术上讲,这个生成器表达式有效:

((globals().__setitem__('__acc', globals()['__acc'] + x), globals()['__acc'])[1] for x in (globals().__setitem__('__acc', 0), iterable)[1])

(我不确定这是否可移植。它可能依赖于实现定义的行为。)

或者,如果可以引入一个本地人:

v = [0]
((v.append(v.pop() + x), v[0])[1] for x in iterable)

在任何情况下,使用此类代码的人都会被枪决。这是一个大规模的黑客攻击,是对可读性和常识的侮辱,没有任何理由或吸引力的迹象。

【讨论】:

  • 哇。使用setitem() 使变量的使用看起来像一种函数式方法。真是丑死了⁺¹ 为此。
  • 我刚找到:v=[],后面跟着[ len(v.__iadd__(x*[0])) for x in [23,42,78,101] ]。你怎么看? ;-)
  • @Alfe 如果允许在单独的语句中引入局部变量,我可以做得更好(将编辑)。我认为这是禁止的 :-) 您的版本具有基本上以一元计数的巨大缺点,即它花费的时间和内存与总和成正比,而不是与被加数的数量成正比。 sum(v.__iadd__([x])) ... 解决了这个问题,但在求和数上仍然是二次方。
  • 我的建议只是为了好玩。但也许最好也说明问题所在。
  • 顺便说一句,为了避免代码重复,我使用变量没有问题;它只是不应该使用它来迭代地总结数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
相关资源
最近更新 更多