13

Right now I am tracking my index in side the loop like this

index = 0
for entry in longList:
    if entry == 'foo':
        print index
    index += 1

is there a better way to do this?

John
  • 13,197
  • 7
  • 51
  • 101

6 Answers6

21
for index, entry in enumerate(longList):
    if entry == 'foo':
        print index
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
10

Use the enumerate() built-in function.

for index, entry in enumerate(longList):
    if entry == 'foo':
        print index

However, in your specific case, you can simply do index = longList.index("foo")

EDIT: If you want to find the indices of multiple matches pretty much as fast as is possible in pure Python, the following code should do the trick:

indices = tuple(index for index, element in enumerate(longList) if element=='foo')
Chinmay Kanchi
  • 62,729
  • 22
  • 87
  • 114
6

I like list comprehension :)

[index for (index,entry) in enumerate(longList) if entry == 'foo']
steabert
  • 6,540
  • 2
  • 26
  • 32
  • +1, but the parenthesis around `(index, entry)` are not required. Remember, in Python commas make tuples, not parenthesis. Also, it's usually better to use a generator expression rather than a list comprehension. So, `(index for index, entry in enumerate(longList) if entry == 'foo')`. – Chinmay Kanchi Aug 29 '11 at 21:57
  • 1
    with parenthesis it is easier to read for me :) Indeed, if you only want to print, take a generator. – steabert Aug 30 '11 at 06:29
5

Yes, the best way is to do this:

longList.index('foo')
Sam Starling
  • 5,298
  • 3
  • 35
  • 52
  • 1
    +1, however, this will raise `ValueError` if `"foo"` isn't a member of `longList` whereas the OP's code will simply not print anything. – Tim Pietzcker Aug 29 '11 at 17:34
  • 8
    And if we are getting particular, it won't find duplicates. – Bill Lynch Aug 29 '11 at 17:34
  • 2
    I was doing this but when I run it over several thousand entries it keeps getting slower and slower the deeper I get into the list. Which is why I am using the loop I am using now. – John Aug 29 '11 at 17:35
  • 2
    @johnthexiii: You call `.index()` only once. It's definitely faster than any Python code you write yourself since it's a C function. – Tim Pietzcker Aug 29 '11 at 17:36
  • 3
    Yes but what If I have several entries that match 'foo'? Then isn't going to perform several searches, thus slowing everything down? – John Aug 29 '11 at 17:39
  • Ah, you didn't specify that you wanted to find multiple instances. – Sam Starling Aug 29 '11 at 17:57
3

Using enumerate would be a better idea.

for ind,item in enumerate(longList):
    if item == 'foo':
        print ind
3

If your list is really long and static, you should consider using a lookup table (actually, a dictionary of index lists with the entry as the key). It will almost pay for itself after the first search, since you currently always iterate over all the elements.

from collections import defaultdict

# Create and fill the table (only once or whenever the list changes)
lookupTable = defaultdict(list)
for index, entry in enumerate(longList):
    lookupTable[entry].append(index)

# Search the list (as many times as you want)
indexes = lookupTable.get('foo')
# and you get either 'None' or a list of indexes '[1,10,20]'
alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • +1 I could see a lot of application for this, I'll have to do some research on this. – John Aug 30 '11 at 12:22