这可以写成python reduce函数吗?

时间:2011-05-08 00:08:06

标签: python

你能通过使用map和/或reduce函数使这更加pythonic吗?它只是对每一对连续数字的乘积求和。

topo = (14,10,6,7,23,6)
result = 0
for i in range(len(topo)-1):
    result += topo[i]*topo[i+1]

7 个答案:

答案 0 :(得分:9)

这是我能想到的最好的方式:

import operator
sum(map(operator.mul, topo[:-1], topo[1:]))

修改:我刚刚发现有更好的方法可以做到这一点:

import operator
import itertools

def pairwise(iterable):
    a, b = itertools.tee(iterable)
    next(b, None)
    return a, b

def sum_products(l):
    return sum(itertools.imap(operator.mul, *pairwise(l)))

成对函数的信用转到itertools文档。

速度更快,占用内存更少。当然,它不那么简洁。

答案 1 :(得分:6)

您可以像这样使用mapreduce,但我不相信它更像pythonic:

reduce( lambda x, y: x + y, map( lambda x, y: x * y, topo[:-1], topo[1:]) )

这个sum +生成器表达式可能更简单:

sum(topo[x] * topo[x+1] for x in xrange(len(topo)-1))

答案 2 :(得分:1)

这有效:

mult = lambda (x, y): x * y
pairs = zip(list(topo), list(topo)[1:])
result = sum(map(mult, pairs))

但可能更难理解。

答案 3 :(得分:1)

使用列表理解而不是地图应该有效:

>>> topo = (14,10,6,7,23,6)
>>> sum((x*y for x,y in zip(topo[:-1],topo[1:])))
541
>>> 

>>> sum((topo[i]*topo[i+1] for i in range(len(topo)-1)))
541

答案 4 :(得分:0)

我不会称之为pythonic,虽然它看起来更酷,reduce不适合这里:

def func(first, *rest):
    return reduce(lambda (x,y),z:(x+y*z,z), rest, (0,first))[0]

请注意(x,y),z的用法仅为2.x。

答案 5 :(得分:0)

使用reduce和Python< 3.X:

from itertools import tee, izip

#recipe from http://docs.python.org/library/itertools.html#recipes
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

reduce(lambda s, (x, y):s + x * y, pairwise(topo), 0)

with map:

from operator import mul
from itertools import tee

a, b = tee(topo)
next(b, None)

sum(map(mul, a, b))

答案 6 :(得分:0)

这也可以得到你的答案

a= [14,10,6,7,23,6]
reduce(lambda a,b: a+b,  map(lambda (x,y): x*y, map(lambda i:(a[i],a[i+1]), range(len(a)-1))  ) )