user1447941
user1447941

Reputation: 3895

Is there a way to get the next item in a list by knowing the current item's value?

my_list = ['apple', 'pear', 'orange', 'raspberry']

# I know that I'm always looking for pear.
print 'pear' in my_list # prints True

# I want to be able to get a key by its value.
pear_key = my_list['pear'].key # should be 1

# Print the next item in the list.
print my_list[pear_key + 1] # should print orange

I know that pear will always be an item in my list (not the position though), and I'm looking for a way to get the value of the next item in that list, either by getting the current key by knowing its value and advancing it by one (like I did in the example above) or by using something like my_list.next.

Upvotes: 2

Views: 2002

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213223

You can use index over list to find a particular value: -

try:
    print my_list[my_list.index('pear') + 1]
except (IndexError, ValueError), e:
    print e

Upvotes: 1

Jon Clements
Jon Clements

Reputation: 142126

try:
    pos = my_list.index('pear')
    print my_list[pos + 1]
    # orange
except IndexError as e:
    pass # original value didn't exist or was end of list, so what's +1 mean?

You could of course pre-cache it, by using (think it's probably the itertools pair recipe)

from itertools import tee
fst, snd = tee(iter(my_list))
next(snd, None)
d = dict(zip(fst, snd))

But then you lose the fact of whether it was in the original list, or just didn't have a logical next value.

Upvotes: 5

Gareth Latty
Gareth Latty

Reputation: 88977

While the simplest solution has been given, if you want to do this on a generic iterator, rather than a list, the simplest answer is to use itertools.dropwhile():

import itertools

def next_after(iterable, value):
    i = itertools.dropwhile(lambda x: x != value, iterable)
    next(i)
    return next(i)

Which can be used like so:

>>> next_after(iter(my_list), "pear")
'orange'

Do note that this is a slower and less readable solution if you are working on a list. This is simply a note for an alternative situation.

You could also produce a version with more descriptive errors:

def next_after(iterable, value):
    i = itertools.dropwhile(lambda x: x != value, iterable)
    try:
        next(i)
    except StopIteration:
        raise ValueError("{} is not in iterable".format(repr(value)))
    try:
        return next(i)
    except StopIteration:
        raise ValueError("{} is the last value in iterable".format(repr(value)))

Upvotes: 2

defuz
defuz

Reputation: 27581

Use this:

>>> my_list[my_list.index('pear') + 1]
'orange'

Note that if this is the last value in the list, you get an exception IndexError.

Upvotes: 2

Related Questions