views:

112

answers:

7

Possible Duplicates:
Python - Previous and next values inside a loop
python for loop, how to find next value(object)?

Hi, everyone.

I've got a list contains a lot of elements, I iterate the list using a for loop. For example

li = [2,31,321,41,3423,4,234,24,32,42,3,24,,31,123]

for (i in li):
    print i

But I want to get the previous element of i, how to achieve that?

I do not have to use a for loop, so feel free to change anything here. Thank you!

+1  A: 

Use a loop counter as an index. (Be sure to start at one so you stay in range.)

for i in range(1,len(li)):
  print li[i], li[i-1]
JoshD
+2  A: 

Just keep track of index and get the previous item by index

li = range(10)

for i, item in enumerate(li):
    if i > 0:
        print item, li[i-1]

print "or..."   
for i in range(1,len(li)):
    print li[i], li[i-1]

output:

1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
or...
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8

another alternative is to remember the last item e.g.

last_item = None
for item in li:
    print last_item, item
    last_item = item
Anurag Uniyal
A: 
li = [2,31,321,41,3423,4,234,24,32,42,3,24,,31,123]

counter = 0
for l in li:
    print l
    print li[counter-1] #Will return last element in list during first iteration as martineau points out.
    counter+=1
Justin Myles Holmes
You're wrong about an exception being raised the first iteration. `alist[-1]` is the last element of the list. Doesn't sound like you tried running it yourself -- not worth a downvote, though.
martineau
Thank you - I learned something today. :-)
Justin Myles Holmes
+5  A: 

Normally, you use enumerate or range() to go through the elements. Here's an alternative

>>> li = [2,31,321,41,3423,4,234,24,32,42,3,24,31,123]
>>> zip(li[1:],li)
[(31, 2), (321, 31), (41, 321), (3423, 41), (4, 3423), (234, 4), (24, 234), (32, 24), (42, 32), (3, 42), (24, 3), (31, 24), (123, 31)]

the 2nd element of each tuple is the previous element of the list.

ghostdog74
+ 1 Great answer!!
rubik
Why did you use the term `li[1::]` instead of `li[1:]` in the second line?
martineau
Just a typo. fixed. thanks
ghostdog74
Yes, this does work, but if your list is really large, do you really want to take the performance hit of creating a second really large list (with `li[1:]`)?
ma3
I already said its an alternative. Of course if the list is REALLY large, then don't use this method. simple as that.
ghostdog74
+3  A: 

you can use zip:

for a, b in zip(li, li[1:]):
  print a, b

or, if you need to do something a little fancier, because creating a list or taking a slice of li would be inefficient (for some reason...),

import itertools

readahead = iter(li)
next(readahead)

for a, b in itertools.izip(li, readahead)
    print a, b
TokenMacGuy
+1 for the itertools answer, not the first. The first is fine if the list is small, but if the list is really large, creating a copy would be inefficient.
ma3
+1  A: 
j = None
for i in li:
    print j
    j = i
kindall
A: 

An option using the itertools recipe from here:

from itertools import tee
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

for i, j in pairwise(li):
    print i, j
Muhammad Alkarouri
The part 2 of @TokenMacGuy's answer seems like a lot simpler way to accomplish this.
martineau
@martineau: Not a lot. The only real difference is the use of `tee`. They achieve different things. @TokenMacGuy's answer doesn't work if `li` is a general iterator rather than a list, it skips pairs. That is the reason `tee` is used here. I was trying more to draw attention to the beautiful `itertools` recipes (`pairwise` is copied from there) rather than reinventing the wheel.
Muhammad Alkarouri