How can I do thing like this in python?
foo = somevalue
previous = next = 0
for (i=1; i<objects.length(); i++) {
if (objects[i]==foo){
previous = objects[i-1]
next = objects[i+1]
}
}
How can I do thing like this in python?
foo = somevalue
previous = next = 0
for (i=1; i<objects.length(); i++) {
if (objects[i]==foo){
previous = objects[i-1]
next = objects[i+1]
}
}
You could just use index
on the list to find where somevalue
is and then get the previous and next as needed:
def find_prev_next(elem, elements):
previous, next = None, None
index = elements.index(elem)
if index > 0:
previous = elements[index -1]
if index < (len(elements)-1):
next = elements[index +1]
return previous, next
foo = 'three'
list = ['one','two','three', 'four', 'five']
previous, next = find_prev_next(foo, list)
print previous # should print 'two'
print next # should print 'four'
using conditional expressions for conciseness for python >= 2.5
def prenext(l,v) :
i=l.index(v)
return l[i-1] if i>0 else None,l[i+1] if i<len(l)-1 else None
# example
x=range(10)
prenext(x,3)
>>> (2,4)
prenext(x,0)
>>> (None,2)
prenext(x,9)
>>> (8,None)
Solutions until now only deal with lists, and most are copying the list. In my experience a lot of times that isn't possible.
Also, they don't deal with the fact that you can have repeated elements in the list.
The title of your question says "Previous and next values inside a loop", but if you run most answers here inside a loop, you'll end up iterating over the entire list again on each element to find it.
So I've just created a function that. using the itertools
module, splits and slices the iterable, and generates tuples with the previous and next elements together. Not exactly what your code does, but it is worth taking a look, because it can probably solve your problem.
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
Then use it in a loop, and you'll have previous and next items in it:
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, next in previous_and_next(mylist):
print "Item is now", item, "next is", next, "previous is", previous
The results:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
It'll work with any size list (because it doesn't copy the list), and with any iterable (files, etc). This way you can just iterate over the sequence, and have the previous and next items available inside the loop. No need to search again for the item in the sequence.
Here's a version using generators with no boundary errors:
def trios(input):
input = iter(input) # make sure input is an iterator
try:
prev, current = input.next(), input.next()
except StopIteration:
return
for next in input:
yield prev, current, next
prev, current = current, next
def find_prev_next(objects, foo):
prev, next = 0, 0
for temp_prev, current, temp_next in trios(objects):
if current == foo:
prev, next = temp_prev, temp_next
return prev, next
print find_prev_next(range(10), 1)
print find_prev_next(range(10), 0)
print find_prev_next(range(10), 10)
print find_prev_next(range(0), 10)
print find_prev_next(range(1), 10)
print find_prev_next(range(2), 10)
Please notice that the boundary behavior is that we never look for "foo" in the first or last element, unlike your code. Again, the boundary semantics are strange...and are hard to fathom from your code :)