开发者

Can this be written as a python reduce function?

开发者 https://www.devze.com 2023-03-04 20:09 出处:网络
Can you make this more pytho开发者_如何学Cnic by using the map and/or reduce functions? it just sums the products of every consecutive pair of numbers.

Can you make this more pytho开发者_如何学Cnic by using the map and/or reduce functions? it just sums the products of every consecutive pair of numbers.

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


This is the nicest way I can think of:

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

Edit: I've just found out there's a better way to do this:

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)))

Credit for pairwise function goes to the itertools documentation.

This is faster and uses less memory. Of course, it's less concise.


You can use map and reduce like this, but I'm not convinced it's more pythonic:

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

Probably simpler is this sum + generator expression:

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


This works:

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

but is probably harder to understand.


Instead of map using a list comprehension should work:

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

or

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


I wouldn't call this pythonic, though it looks cooler, reduce doesn't fit in here:

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

Note the usage of (x,y),z is 2.x only.


With reduce and 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))


this can also get your answer

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))  ) )
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号