1

I would like to know if there is a save and fast way of retrieving the index of an element in a list in python 3.

Idea:

# how I do it 
try:
    test_index = [1,2,3].index(4) # error
except:
    # handle error


# how I would like to do it: 
test_index = [1,2,3].awesome_index(4) # test_index = -1
if test_index == -1: 
    # handle error

The reason, why I would like to not use try, except is because try-except appears to be a little bit slower that an if-statement. Since I am handling a lot of data, performance is important to me.

Yes, I know that I could implement awesome_index by simply looping through the list, but I assume that there already is a function doing exactly that in a very efficient way.

User12547645
  • 6,955
  • 3
  • 38
  • 69
  • If you have bottlenecks in your code, this sure wouldn't be it. – cs95 Jul 01 '18 at 19:25
  • Possible duplicate of [Python: Find in list](https://stackoverflow.com/questions/9542738/python-find-in-list) – khelwood Jul 01 '18 at 19:34
  • @khelwood disagree, that question doesn't give him the answer – Bharel Jul 01 '18 at 19:39
  • @Bharel the answers give numerous suggestions for how to find the index of an item in a list without raising an exception. Just because they're different from your answer doesn't mean they're not answers – khelwood Jul 01 '18 at 19:43
  • @khelwood The OP is rather smart as he said, "Yes, I know that I could implement awesome_index by simply looping through the list". They all loop over it. – Bharel Jul 01 '18 at 19:44
  • Yes and so does yours. – khelwood Jul 01 '18 at 19:46
  • @khelwood Mine doesn't. O(1) lookup if it doesn't and max O(n) only in case it exists. Much more efficient for a long list with many searches my friend – Bharel Jul 01 '18 at 19:47
  • Thanks @khelwood. What I mean is, that there were already a lot of people with the same sort of problem. I am sure at least one of them came up with a very good solution to that problem. Why not use that solution? – User12547645 Jul 01 '18 at 19:51
  • @Bharel If you were doing multiple searches on the same list, you'd be better off storing the indexes in a dict and get a genuine O(1) solution, instead of putting the elements in a set and getting a _sometimes_ O(1) solution. The OP doesn't say they are doing multiple searches in the same list. So your answer is just another alternative suggestion that might be preferable in some circumstances. – khelwood Jul 01 '18 at 19:52
  • @khelwood, well then, you are welcome to add `dict()` as an option. It will prove inferior in case of `insert()`s but you're right, it's a better solution. Want to post it as a solution or shall I modify mine? – Bharel Jul 01 '18 at 19:56
  • @Bharel no thanks. I try not to answer duplicates. – khelwood Jul 01 '18 at 20:01

1 Answers1

1

There is no such thing, but I like your thinking, so let's built upon it:

If you have only one index, and create many queries against it, why not maintain a set() or a dict() right next to that index?

numbers = [1,2,3]
unique_nunbers = set(numbers)

if 4 in unique_nunbers:
  return numbers.index(4)

Dict option:

numbers = [1,2,3]
unique_nunbers = dict(zip(numbers, range(len(numbers))))

index = unique_nunbers.get(4)
if index is None:
    # Do stuff

Lookups inside sets and dicts O(1), thus 4 in unique_numbers costs almost nothing. Iterating over the whole list in case something doesn't exist though, is a wasted O(n) operation.

This way, you have a way more efficient code, with a better algorithm, and no excepctions!

Keep in mind the same thing cannot be said for 4 in numbers, as it iterates over the whole list.

Bharel
  • 23,672
  • 5
  • 40
  • 80
  • Thank you very much for the suggestion! I will try this! – User12547645 Jul 01 '18 at 19:46
  • Sure! You're welcome to time-test it and see it's much faster for multiple lookups. Remember, you should create the `set()` only once! If you have any more questions, feel free to ask. – Bharel Jul 01 '18 at 19:49
  • @User12547645 if you do not happen to modify the list too much, I highly suggest using a `dict()` instead of a set, as @khelwood suggested. It will give you a genuine O(1) operation. – Bharel Jul 01 '18 at 19:59
  • Yea, I think that would really make sense. Thank you for the suggesiton – User12547645 Jul 01 '18 at 20:22