# reduce()--what is it good for? (was: Re: reduce() anomaly?)

Alex Martelli aleax at aleax.it
Fri Nov 7 18:21:54 CET 2003

```Georgy Pruss wrote:

> seq=[1,3,4,7]
> map( int.__sub__, seq[1:], seq[:-1] ) # nearly twice faster than
> ....zip.... for long arrays

If this is a race, then let's measure things properly and consider
a few more alternatives, shall we...?

[alex at lancelot xine-lib-1-rc2]\$ python a.py
reduce: 100 loops, best of 3: 13.8 msec per loop
zip: 100 loops, best of 3: 18 msec per loop
izip: 100 loops, best of 3: 7.6 msec per loop
w2: 100 loops, best of 3: 7.1 msec per loop
wib: 100 loops, best of 3: 12.7 msec per loop
loop: 100 loops, best of 3: 8.9 msec per loop
map: 100 loops, best of 3: 7.6 msec per loop

itertools.w2 is an experimental addition to itertools which I
doubt I'll be allowed to put in (gaining less than 10% wrt the
more general izip is hardly worth a new itertool, sigh).  But,
apart from that, map and izip are head to head, and the plain
good old Python-coded loop is next best...!  reduce is slowest.

My code...:

if __name__ != '__main__':
def difs_reduce(seq):
differences = []
def neighborDifference(left, right, accum=differences.append):
accum(right - left)
return right
reduce(neighborDifference, seq)
return differences

def difs_zip(seq):
return [ b-a for a, b in zip(seq,seq[1:]) ]

import itertools
def difs_izip(seq):
return [ b-a for a, b in itertools.izip(seq,seq[1:]) ]

def difs_w2(seq, wib=itertools.w2):
return [ b-a for a, b in wib(seq) ]

def window_by_two(iterable):
it = iter(iterable)
last = it.next()
for elem in it:
yield last, elem
last = elem

def difs_wib(seq, wib=window_by_two):
return [ b-a for a, b in wib(seq) ]

def difs_loop(seq):
differences = []
it = iter(seq)
a = it.next()
for b in it:
differences.append(b-a)
a = b
return differences

def difs_map(seq):
return map(int.__sub__, seq[1:], seq[:-1])

if __name__ == '__main__':
import timeit
bargs = ['-c', '-simport a', '-sx=range(9999)']
funs = 'reduce zip izip w2 wib loop map'.split()
for fun in funs:
args = bargs + ['a.difs_%s(x)' % fun]
print '%8s:' % fun,
timeit.main(args)

Alex

```