python中Haskell scanl的等价物 [英] Equivalent of Haskell scanl in python

查看:117
本文介绍了python中Haskell scanl的等价物的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有相当于Haskell scanl 的python内置函数,如 reduce 相当于 foldl



这样做:

  Prelude> scanl(+)0 [1..10] 
[0,1,3,6,10,15,21,28,36,45,55]

问题不在于如何实现它,我已经有2个实现,如下所示(但是,如果您有更优雅的实现,请随时显示

第一次执行:减少多次
def scanl(f,base,l):
ls = [l [0:i] for i in range(1,len(l)+ 1)]
return [base] + [reduce(f,x,base)for x in ls]

print scanl(operator.add,0,range(1,11))




$ b $ p $ $ $ $ $ $ $ $ $ 1,3,6,10,15,21,28,36,45,55]

第二执行:

 #使用累加器有效,
def scanl2(f,base,l):
res = [base]
acc = base
for x in l:
acc = f(acc,x)
res + = [acc]
return res

print scanl2(operator.add,0,range(1 ,11))

给出:

 [0,1,3,6,10,15,21,28,36,45,55] 

谢谢:)

解决方案



  def scanl(f,base,l):
for x in l:
base = f (base,x)
产出基数

使用它:

 导入运算符
列表(scanl(operator.add,0,range(1,11)))

Python 3.x有 itertools.accumulate(iterable,func = operator.add) 。它的实现如下。这个实现可能会给你一些想法:

$ $ $ $ $ $ c $ def def accumulate(iterable,func = operator.add)
'返回运行总计'
#accumulate([1,2,3,4,5]) - > 1 3 6 10 15
#accumulate([1,2,3,4,5],operator.mul) - > 1 2 6 24 120
it = iter(可迭代的)
total = next(it)
产生的总和
中的元素:
total = func(total,元素)
收益总额


I would like to know if there is a built in function in python for the equivalent Haskell scanl, as reduce is the equivalent of foldl.

Something that does this:

Prelude> scanl (+) 0 [1 ..10]
[0,1,3,6,10,15,21,28,36,45,55]

The question is not about how to implement it, I already have 2 implementations, shown below (however, if you have a more elegant one please feel free to show it here).

First implementation:

 # Inefficient, uses reduce multiple times
 def scanl(f, base, l):
   ls = [l[0:i] for i in range(1, len(l) + 1)]
   return [base] + [reduce(f, x, base) for x in ls]

  print scanl(operator.add, 0, range(1, 11))

Gives:

[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]

Second implementation:

 # Efficient, using an accumulator
 def scanl2(f, base, l):
   res = [base]
   acc = base
   for x in l:
     acc = f(acc, x)
     res += [acc]
   return res

 print scanl2(operator.add, 0, range(1, 11))

Gives:

[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]

Thank you :)

解决方案

You can use this, if its more elegant:

def scanl(f, base, l):
    for x in l:
        base = f(base, x)
        yield base

Use it like:

import operator
list(scanl(operator.add, 0, range(1,11)))

Python 3.x has itertools.accumulate(iterable, func= operator.add). It is implemented as below. The implementation might give you ideas:

def accumulate(iterable, func=operator.add):
    'Return running totals'
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
    it = iter(iterable)
    total = next(it)
    yield total
    for element in it:
        total = func(total, element)
        yield total

这篇关于python中Haskell scanl的等价物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆