Referencing list entries within a for loop without indexes, possible?
Question: A question of particular interest about python for loops. Engineering programs
often require values at previous or future indexes, such as:

    
    
    for i in range(0,n):
        value = 0.3*list[i-1] + 0.5*list[i] + 0.2*list[i+1]
    

etc...

However I rather like the nice clean python syntax:

    
    
    for item in list:
        #Do stuff with item in list
    

or for a list of 2d point data:

    
    
    for [x,y] in list:
        #Process x, y data
    

I like the concept of looping over a list without explicitly using an index to
reference the items in the list. I was wondering if there was a clean way to
grab the previous or next item without looping over the index (or without
keeping track of the index independently)?

EDIT:

Thanks Andrew Jaffe (and by proxy Mark Byers) and gnibbler for the simple,
extendable examples. I wasn't aware of the itertools or nwise modules till
now. John Machin - thanks for the very complex example of what NOT to do. You
put a lot of effort into this example, obviously the somewhat recursive
algorithm I presented cannot produce a list with the same number of elements
as the input list and it presents problems if not using explicit indexes. An
algorithm like this would commonly occur in signal processing.


Answer: Here's a recipe, based on the
[itertools](http://docs.python.org/library/itertools.html#recipes) pairwise
code, which does general n-wise grouping:

    
    
    import itertools
    
    def nwise(iterable, n=2):
        "s->(s_0,s_1, ..., s_n), (s_1,s_2,..., s_n+1), ... "
        ntup = itertools.tee(iterable, n)
        for i, item in enumerate(ntup):
            for ii in range(i):
                next(item, None)
        return itertools.izip(*ntup)
    

Which can be used thusly:

    
    
    >>> import nwise
    >>> ll = range(10)
    >>> for tup in nwise.nwise(ll,3): print tup
    ... 
    (0, 1, 2)
    (1, 2, 3)
    (2, 3, 4)
    (3, 4, 5)
    (4, 5, 6)
    (5, 6, 7)
    (6, 7, 8)
    (7, 8, 9)
    

[Thanks to Mark Byers' answer for the idea]

