Accessing next/prev element while for looping
Bengt Richter
bokr at oz.net
Sun Dec 18 08:23:12 EST 2005
On Sun, 18 Dec 2005 04:23:21 -0700, Joseph Garvin <k04jg02 at kzoo.edu> wrote:
>When I first came to Python I did a lot of C style loops like this:
>
>for i in range(len(myarray)):
> print myarray[i]
>
>Obviously the more pythonic way is:
>
>for i in my array:
> print i
>
>The python way is much more succinct. But a lot of times I'll be looping
>through something, and if a certain condition is met, need to access the
>previous or the next element in the array before continuing iterating. I
>don't see any elegant way to do this other than to switch back to the C
>style loop and refer to myarray[i-1] and myarray[i+1], which seems
>incredibly silly given that python lists under the hood are linked
>lists, presumably having previous/next pointers although I haven't
>looked at the interpeter source.
>
>I could also enumerate:
>
>for i, j in enumerate(myarray):
> print myarray[i], j # Prints each element twice
>
>And this way I can keep referring to j instead of myarray[i], but I'm
>still forced to use myarray[i-1] and myarray[i+1] to refer to the
>previous and next elements. Being able to do j.prev, j.next seems more
>intuitive.
>
>Is there some other builtin somewhere that provides better functionality
>that I'm missing?
I don't know of a builtin, but you could make an iterator that gives you
your sequence as (prev, curr, next) item tuples, where curr is the normal
single item in for curr in my_array: ... e.g.,
>>> def pcniter(seq, NULL=NotImplemented):
... seqiter = iter(seq)
... prev = curr = NULL
... try: next = seqiter.next()
... except StopIteration: return
... for item in seqiter:
... prev, curr, next = curr, next, item
... yield prev, curr, next
... yield curr, next, NULL
...
>>> for prev, curr, next in pcniter('abcdef', '\x00'): print '%8r'*3 %( prev, curr, next)
...
'\x00' 'a' 'b'
'a' 'b' 'c'
'b' 'c' 'd'
'c' 'd' 'e'
'd' 'e' 'f'
'e' 'f' '\x00'
>>> for prev, curr, next in pcniter(xrange(4), 'NULL' ): print '%8r'*3 %( prev, curr, next)
...
'NULL' 0 1
0 1 2
1 2 3
2 3 'NULL'
If you want to assign back into myarray[i-1] etc, you'd still need to enumerate, but you could
combine with the above it was useful.
Regards,
Bengt Richter
More information about the Python-list
mailing list