English 中文(简体)
履历表
原标题:List comprehension for running total

我想从人数清单中抽出一席之地。

为求精起见,我首先使用<代码>range的顺序编号。

a = range(20)

runningTotal = []
for n in range(len(a)):
    new = runningTotal[n-1] + a[n] if n > 0 else a[n]
    runningTotal.append(new)

# This one is a syntax error
# runningTotal = [a[n] for n in range(len(a)) if n == 0 else runningTotal[n-1] + a[n]]

for i in zip(a, runningTotal):
    print "{0:>3}{1:>5}".format(*i)

产量

  0    0
  1    1
  2    3
  3    6
  4   10
  5   15
  6   21
  7   28
  8   36
  9   45
 10   55
 11   66
 12   78
 13   91
 14  105
 15  120
 16  136
 17  153
 18  171
 19  190

如你所知,我先把一份空名单(<>条码/代码>,然后在每一座程中填入<条码>。 是否像一个清单理解那样,有更可取的办法?

最佳回答
问题回答

一份清单核对表没有很好的(清晰的、便携式的)方式来提及其大楼清单。 一种良好和明智的做法可能是在创造者中开展工作:

def running_sum(a):
  tot = 0
  for item in a:
    tot += item
    yield tot

当然,要把这一清单作为清单使用<代码>(running_sum(a)。

如果您能够使用numpy,则它拥有一个名为cumsum的内在功能。

import numpy as np
tot = np.cumsum(a)  # returns a np.ndarray
tot = list(tot)     # if you prefer a list

我不敢肯定地说,但我认为以下是更加简单和更加直观的(以额外变量的成本计算):

a = range(20)

runningTotal = []

total = 0
for n in a:
  total += n
  runningTotal.append(total)

采取同样做法的功能方式是:

a = range(20)
runningTotal = reduce(lambda x, y: x+[x[-1]+y], a, [0])[1:]

......但是,这远不易读/可持续,等等。

@Omnifarous建议,应当加以改进,以便:

a = range(20)
runningTotal = reduce(lambda l, v: (l.append(l[-1] + v) or l), a, [0])

......但我仍然认为,与我最初的建议相比,这种理解不那么直接。

摘录Kernighan语:“偷窃是最早撰写法典的两倍。 因此,如果你尽可能地写成该守则,那么根据定义,你就不够聪明才智,无法加以推断。

www.un.org/Depts/DGACM/index_spanish.htm 可在<>的2行中实施。

使用缺省参数消除了在外维持一个辅助变量的需要,然后我们就在名单上填写了map<>。

def accumulate(x, l=[0]): l[0] += x; return l[0];
map(accumulate, range(20))

当我们拿到清单的总和时,我们指定了一台加固器(memo),然后通过清单行走,将双功能“x+y”应用到每个要素和加压器。 从程序上看,情况如下:

def mySum(list):
    memo = 0
    for e in list:
        memo = memo + e
    return memo

这是一种共同模式,对除提取钱以外的东西有用——我们可以将其概括为任何双亲功能,我们把这种功能作为参数供应,并且让打电话者具体说明初步价值。 这使我们有了以下功能:reduce,、 / . /code>, 或inject>:<>?

def myReduce(function, list, initial):
    memo = initial
    for e in list:
        memo = function(memo, e)
    return memo

def mySum(list):
    return myReduce(lambda memo, e: memo + e, list, 0)

在Zahur 2,reduce <>/code>是建构功能,但在Avry 3中,该功能被移至functools。 模块:

from functools import reduce

我们可以根据我们作为第一种论点所提供的职能,用<条码>减去<>>>>>的冷却。 如果我们把“总”改为“清单分类”,将“零”改为“豁免清单”。 职能:

def myCopy(list):
    return reduce(lambda memo, e: memo + [e], list, [])

myCopy(range(10))
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果我们添加一个<代码>transform功能,作为另一个参数,以copy,并在设计之前适用该功能,我们就获得<编码>> 地图<>。

def myMap(transform, list):
    return reduce(lambda memo, e: memo + [transform(e)], list, [])

myMap(lambda x: x*2, range(10))
> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

如果我们添加一个<代码>predicate功能,该功能以e为参数,并回归一个细菌,并用该代码来决定是否加以压缩,我们就获得<编码>filter:

def myFilter(predicate, list):
    return reduce(lambda memo, e: memo + [e] if predicate(e) else memo, list, [])

myFilter(lambda x: x%2==0, range(10))
> [0, 2, 4, 6, 8]

。 由于<代码>reduce<>/code>,因此没有相应的核对表。 只需要回到一份清单(见sum<>/code>,较早时,这段话也是为了作为内在功能提供。

由此可见,对于计算一个总合而言,<代码>reduce<>/code>的造物能力恰恰是我们想要的,或许是解决这一问题的最合法途径,尽管其声誉(连同lambda)是非致命的shi。 缩略语 留在其原有价值的印本上,其编号为 reductionsscanl<>>> >?

def reductions(function, list, initial):
    return reduce(lambda memo, e: memo + [function(memo[-1], e)], list, [initial])

因此,我们现在可以确定:

def running_sum(list):
    first, rest = list[0], list[1:]
    return reductions(lambda memo, e: memo + e, rest, first)

running_sum(range(10))
> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

虽然从概念上说,这种准确的做法在实际中与沙捞越差。 由于Zahur slist.append()> 变更了已经制定但又未返回的一览表,我们可以有效地将清单用在Mlambda,而必须使用+。 这份新的清单与迄今累积清单(即O(n)业务)的时间相称。 由于我们已在O(n)for loop of reduce/code>内重新编号。 当我们这样做时,总体时间复杂性会波及O(n2)。

以下述语文分发:

class Array
  def reductions(initial, &proc)
    self.reduce [initial] do |memo, e|
      memo.push proc.call(memo.last, e)
    end
  end
end

def running_sum(enumerable)
  first, rest = enumerable.first, enumerable.drop(1)
  rest.reductions(first, &:+)
end

running_sum (0...10)
> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

同样,在《 Java本:<><><>>><>>>>>>>>>>>>>> > >-> ><>>>> >> > >> > > > >>>> >>>>> > > > >------------------------------------------------------------------>-----------------------------------------------------------------------------------------------------------------

function reductions(array, callback, initial) {
    return array.reduce(function(memo, e) {
        memo.push(callback(memo[memo.length - 1], e));
        return memo;
    }, [initial]);
}

function runningSum(array) {
    var first = array[0], rest = array.slice(1);
    return reductions(rest, function(memo, e) {
        return x + y;
    }, first);
}

function range(start, end) {
    return(Array.apply(null, Array(end-start)).map(function(e, i) {
        return start + i;
    }
}

runningSum(range(0, 10));
> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

因此,我们如何能够在保留一个<条码>削减<>/条码>功能的概念简单化的同时解决这一问题,而我们只是通过<条码>lambda x, y:x+ y,以便建立总合功能? 请在程序上重写<条码>削减。 我们可以确定 问题,虽然我们当时赞成,但事先公布结果清单,以避免ap裂[3]:

def reductions(function, list, initial):
    result = [None] * len(list)
    result[0] = initial
    for i in range(len(list)):
        result[i] = function(result[i-1], list[i])
    return result

def running_sum(list):
    first, rest = list[0], list[1:]
    return reductions(lambda memo, e: memo + e, rest, first)

running_sum(range(0,10))
> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

这是我最热点:O(n)业绩,优化的《程序法》被贴上有意义的名称,在你今后需要写一份把中间价值积累起来的职能时可以重新使用。

  1. The names reduce/reductions come from the LISP tradition, foldl/scanl from the ML tradition, and inject from the Smalltalk tradition.
  2. Python s List and Ruby s Array are both implementations of an automatically resizing data structure known as a "dynamic array" (or std::vector in C++). JavaScript s Array is a little more baroque, but behaves identically provided you don t assign to out of bounds indices or mutate Array.length.
  3. The dynamic array that forms the backing store of the list in the Python runtime will resize itself every time the list s length crosses a power of two. Resizing a list means allocating a new list on the heap of twice the size of the old one, copying the contents of the old list into the new one, and returning the old list s memory to the system. This is an O(n) operation, but because it happens less and less frequently as the list grows larger and larger, the time complexity of appending to a list works out to O(1) in the average case. However, the "hole" left by the old list can sometimes be difficult to recycle, depending on its position in the heap. Even with garbage collection and a robust memory allocator, pre-allocating an array of known size can save the underlying systems some work. In an embedded environment without the benefit of an OS, this kind of micro-management becomes very important.

http://www.python.org/dev/peps/pep-0572/“rel=“nofollow noreferer”>signment expression (PEP 572)(:=营运人),我们可以在一份清单内使用和计算一个变量:

# items = range(7)
total = 0
[(x, total := total + x) for x in items]
# [(0, 0), (1, 1), (2, 3), (3, 6), (4, 10), (5, 15), (6, 21)]

这是:

  • Initializes a variable total to 0 which symbolizes the running sum
  • For each item, this both:
    • increments total by the current looped item (total := total + x) via an assignment expression
    • and at the same time returns the new value of total as part of the produced mapped tuple

我也想做同样的事,以产生我可以使用的双眼——即我制作名单的方式——的累积频率。

[ sum( a[:x] ) for x in range( 1, len(a)+1 ) ]

这里有一个线性时间解决方案:

list(reduce(lambda (c,s), a: (chain(c,[s+a]), s+a), l,(iter([]),0))[0])

例:

l = range(10)
list(reduce(lambda (c,s), a: (chain(c,[s+a]), s+a), l,(iter([]),0))[0])
>>> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

简言之,减幅超过了累计数额和编制清单的清单。 最后<代码>x[0] 清单,<代码>x***为总价值。

另一位一线飞行时间和空间。

def runningSum(a):
    return reduce(lambda l, x: l.append(l[-1]+x) or l if l else [x], a, None)

我在此强调线性空间,因为我在其他拟议答复中看到的大多数单线人——即根据模型<代码> +[摘要]的编码——生成O(n) 清单或发电机,并强调停车场收集者的业绩非常差,与这一点相比。

我将为此使用一条路线:

def runningTotal():
    accum = 0
    yield None
    while True:
        accum += yield accum

tot = runningTotal()
next(tot)
running_total = [tot.send(i) for i in xrange(N)]

你正在寻找两件事:双重(red)和一小 function,把我所呼吁的另一项职能的成果清单保存下来。 我的版本既包括初步参数,也无初步参数;要么是用初步参数加以减少。

def last_or_default(list, default):
    if len(list) > 0:
        return list[-1]
    return default

def initial_or_apply(list, f, y):
    if list == []:
        return [y]
    return list + [f(list[-1], y)]

def running_initial(f, initial):
    return (lambda x, y: x + [f(last_or_default(x,initial), y)])

def running(f):
    return (lambda x, y: initial_or_apply(x, f, y))

totaler = lambda x, y: x + y
running_totaler = running(totaler)
running_running_totaler = running_initial(running_totaler, [])

data = range(0,20)
running_total = reduce(running_totaler, data, [])
running_running_total = reduce(running_running_totaler, data, [])

for i in zip(data, running_total, running_running_total):
    print "{0:>3}{1:>4}{2:>83}".format(*i)

由于“+”操作员的缘故,这将需要很长的时间。 用一种功能性语言,如果正确的话,该清单的构建将是O(n)。

这里是头几行产出:

0   0                      [0]
1   1                   [0, 1]
2   3                [0, 1, 3]
3   6             [0, 1, 3, 6]
4  10         [0, 1, 3, 6, 10]
5  15     [0, 1, 3, 6, 10, 15]
6  21 [0, 1, 3, 6, 10, 15, 21]

这一点并不有效,因为从一开始,它就每时都这样做,但可能的话是:

a = range(20)
runtot=[sum(a[:i+1]) for i,item in enumerate(a)]
for line in zip(a,runtot):
    print line

用3.8和3.8以上的话来说,现在可以使用航海经营者。

xs = range(20)
total = 0
run = [(total := total + d) for d in xs]




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签