Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most efficient way of finding the next element in a tuple

I've got a system in which I often (but not constantly) have to find the next item in a tuple. I'm currently doing this like so:

mytuple = (2,6,4,8,7,9,14,3)
currentelement = 4
def f(mytuple, currentelement):
    return mytuple[mytuple.index(currentelement) + 1]
nextelement = f(mytuple, currentelement)

All elements are unique and I am not stuck with the tuple, I can make it something else earlier in the program if needed.

Since I need to do this a lot, I was wondering whether there is any more efficient way to do this?

like image 259
kramer65 Avatar asked Jun 18 '13 09:06

kramer65


People also ask

Which is the efficient way to change a value in tuple?

Once a tuple is created, you cannot change its values. Tuples are unchangeable, or immutable as it also is called. But there is a workaround. You can convert the tuple into a list, change the list, and convert the list back into a tuple.

How do you find the nth element of a tuple?

The way to get the nth item in a tuple is to use std::get: std::get<n>(my_tuple) .

Which is more efficient tuple or list?

The key takeaways are: The key difference between the tuples and lists is that while the tuples are immutable objects the lists are mutable. This means that tuples cannot be changed while the lists can be modified. Tuples are more memory efficient than the lists.


2 Answers

Use a dict here, dicts provide O(1) lookup compared to list.index which is an O(N) operation.

And this will work for strings as well.

>>> lis = (2,6,4,8,7,9,14,3)
>>> dic = dict(zip(lis, lis[1:]))
>>> dic[4]
8
>>> dic[7]
9
>>> dic.get(100, 'not found') #dict.get can handle key errors
'not found'

A memory efficient version to create the above dict:

>>> from itertools import izip
>>> lis = (2,6,4,8,7,9,14,3)
>>> it1 = iter(lis)
>>> it2 = iter(lis)
>>> next(it2)
2
>>> dict(izip(it1,it2))
{2: 6, 4: 8, 6: 4, 7: 9, 8: 7, 9: 14, 14: 3}
like image 106
Ashwini Chaudhary Avatar answered Sep 25 '22 22:09

Ashwini Chaudhary


You might wish to build an index using a dictionary:

# The list
>>> lis = (2,6,4,8,7,9,14,3)

# build the index
>>> index = dict(zip(lis, range(len(lis))))
>>> index
{2: 0, 3: 7, 4: 2, 6: 1, 7: 4, 8: 3, 9: 5, 14: 6}

# Retrieve position by using the index
>>> index[6]
1
>>> lis[index[6]+1]
4

If your list change over time, you will have to rebuild the index. For a more memory efficient solution, you might prefer using izip instead of `zip̀ as suggested in an other answer.

like image 37
Sylvain Leroux Avatar answered Sep 24 '22 22:09

Sylvain Leroux