adjacent differences with a list comprehension

Alex Martelli aleax at aleax.it
Tue Mar 25 06:50:58 EST 2003


Sean Ross wrote:

> 
> "Greg Ewing (using news.cis.dfn.de)" <me at privacy.net> wrote in message
> news:b5o3o8$2bhikr$1 at ID-169208.news.dfncis.de...
>> I would suggest:
>>
>>    [seq[i+1] - seq[i] for i in xrange(len(seq) - 1)]
>>
>> It's a bit more efficient to boot, since it avoids
>> constructing an intermediate list of tuples.
> 
> True.
> And,
>     import operator
>     map(operator.sub, seq[1:], seq[:-1])
> suffers from the same inefficiency,  but it is faster  ;)

No reason not to give timeit.py a try when discussing speed...:

[alex at lancelot alex]$ python timeit.py -s 'import operator' -s 
'seq=range(1000)' 'x=map(operator.sub, seq[1:], seq[:-1])'
1000 loops, best of 3: 919 usec per loop
[alex at lancelot alex]$ python timeit.py -s 'import operator' -s 
'seq=range(1000)' 'x=[seq[i+1]-seq[i] for i in xrange(len(seq)-1)]'
1000 loops, best of 3: 1.96e+03 usec per loop
[alex at lancelot alex]$ python timeit.py -s 'import operator' -s 
'seq=range(1000)' 'x=map(lambda a, b: a-b, seq[1:], seq[:-1])'
1000 loops, best of 3: 1.69e+03 usec per loop
[alex at lancelot alex]$ python timeit.py -s 'import operator' -s 
'seq=range(1000)' 'x=[a-b for a,b in zip(seq[1:],seq)]'
100 loops, best of 3: 1.78e+03 usec per loop

so, yes: map is way faster when you can pass it a builtin
function from operator (not so much when you need a lambda,
though).  And zip turns out to be a little bit faster (on
this machine) than the xrange-based solution.

One result that surprises me a lot...:

[alex at lancelot alex]$ python timeit.py -s 'import operator' -s 
'seq=range(1000)' 'x=map(int.__sub__, seq[1:], seq[:-1])'
1000 loops, best of 3: 1.68e+03 usec per loop

I have no idea how or why operator.sub can be faster
than int.__sub__ in this case...!


Alex





More information about the Python-list mailing list