views:

137

answers:

3
a = [5, 66, 7, 8, 9, ...]

Is it possible to make an iteration instead of writing like this?

a[1] - a[0]

a[2] - a[1]

a[3] - a[2]

a[4] - a[3]

...

Thank you!

+5  A: 

for a small list in python 2 or any list in python 3, you can use

[x - y for x, y in zip(a[1:], a)]

for a larger list, you probably want

import itertools as it

[x - y for x, y in it.izip(a[1:], a)]

if you are using python 2

And I would consider writing it as a generator expression instead

(x - y for x, y in it.izip(a[1:], a))

This will avoid creating the second list in memory all at once but you will only be able to iterate over it once. If you only want to iterate over it once, then this is ideal and it's easy enough to change if you decide later that you need random or repeated access. In particular if you were going to further process it to make a list, then this last option is ideal.

update:

The fastest method by far is

import itertools as it
import operator as op

list(it.starmap(op.sub, it.izip(a[1:], a)))

$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]'
100 loops, best of 3: 13.5 msec per loop

$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]'
100 loops, best of 3: 8.4 msec per loop

$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))'
100 loops, best of 3: 6.38 msec per loop
aaronasterling
they actually look overly complicated for a trivial task, especially considering the OP's assumed experience. When did ordinary for-loops become a bad thing to use?
Ivo van der Wijk
when the became twice as slow and cruftier to read than a comprehension.
aaronasterling
Ok, I profiled and in this case they're not twice as slow but they're still the slowest by far. 16.8 msec with the same input as I display above. and my point about them being cruftier to read still stands.
aaronasterling
I really don't see what the big deal about a simple damn list comprehension is. It is the correct thing to do in this case and __far__ more readable than some shitty for loop. Also, I see no point in mollycoddling some newb that can't be bothered to read a tutorial.
aaronasterling
@Ivo: Iterating over the indices instead of the elements of an array also introduces additional possibilities for mistakes. For example if you accidentally let your for-loop start at 0 instead of 1, you'd get an index out of bounds error. This is not something you have to worry about using list comprehensions and itertools.
sepp2k
+5  A: 

Sure.

for i in range(1, len(a)):
    print a[i] - a[i-1]

I fail to see what the real problem is here. Have you read the python tutorial?

Ivo van der Wijk
+6  A: 

I acknowledge that such a simple task should not require extra functions, but programming is about abstractions, isn't it? Consecutive pairs (x0, x1), (x1, x2), (x2, x3), ..., are called pairwise combinations (see a python recipe in the itertools docs). And once you have this function in your toolset (which you should have, since Python devs cannot anticipate all your needs), it's as easy as:

a = [5, 66, 7, 8, 9]
for x, y in pairwise(a):
    print y - x
tokland
+1 for mentioning abstractions and for pairwise.
Manoj Govindan