Reputation: 109
Given an input sequence of any type (list/string/range) how do I find the next item in the input following the specified item?
Also, if the item isn't present or nothing follows it, the function should return None
.
I tried converting input type to a list and then finding the position from a list, then getting the next item but this does not work for all input types. I have written something but I know it is not pythonic and it also times out. (codewars challenge: https://www.codewars.com/kata/542ebbdb494db239f8000046/train/python)
My attempt:
def next_item(xs, item):
xs_list = list(xs)
if item in xs_list:
position = xs_list.index(item)
try:
return xs_list[position+1]
except IndexError:
return None
else:
return None
Desired results:
next_item([1, 2, 3, 4, 5, 6, 7, 8], 5)
# 6)
next_item(['a', 'b', 'c'], 'd')
# None)
next_item(['a', 'b', 'c'], 'c')
# None)
next_item('testing', 't')
# # 'e')
next_item(iter(range(1, 3000)), 12)
# , 13)
Upvotes: 3
Views: 165
Reputation: 761
Fastest Solution after testing,
def next_item(ls,item): try: return ls[ls.index(item)+1] except: None
It took 0.886 to run this.
Here's are some other solutions,
def next_item(ls,item): for i in range(len(ls)): if ls[i] == item: return ls[i+1] return None
next_item(range(100000000),9999999)
OUTPUT 1.862
[10000000]
list.index()
def next_item(ls,item): try: return ls[ls.index(item)+1] except: None
next_item(range(100000000),9999999)
OUTPUT 0.886
[10000000]
[]
and Any answer is inside a list, ex: [1]
def next_item(ls,item): return [ls[i+1] for i in range(len(ls)) if ls[i] == item]
next_item(range(100000000),9999999)
OUTPUT 16.481
[10000000]
def next_item(ls,item): a = [ls[i+1] for i in range(len(ls)) if ls[i] == item] if a == []: return None else: return a[0]
next_item(range(100000000),9999999)
OUTPUT 16.389
[10000000]
def next_item(ls, item): ls = iter(ls) return next(next((ls for i in ls if item == i), ls), None)
next_item(range(100000000),9999999)
OUTPUT 0.994
[10000000]
Upvotes: 1
Reputation: 10203
Simple solution:
def next_item(xs, item):
it = iter(xs)
item in it
return next(it, None)
The item in it
tries to find the item and thereby consumes that iterator until it finds the item or until it reaches the end.
Upvotes: 6
Reputation: 15364
Try this:
def next_item(seq, item):
seq = iter(seq)
return next(next((seq for it in seq if item == it), seq), None)
Upvotes: 1
Reputation: 61910
You could use next to return the element that comes after the specified one:
def next_item(seq, e):
iterable = iter(seq)
for i in iterable:
if i == e:
return next(iterable, None)
return None
print(next_item([1, 2, 3, 4, 5, 6, 7, 8], 5))
print(next_item(['a', 'b', 'c'], 'd'))
print(next_item(['a', 'b', 'c'], 'c'))
print(next_item('testing', 't'))
print(next_item(iter(range(1, 3000)), 12))
Output
6
None
None
e
13
Upvotes: 5