184

I am iterating over a list and I want to print out the index of the item if it meets a certain condition. How would I do this?

Example:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position
Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
Sean
  • 5,244
  • 6
  • 28
  • 27

15 Answers15

298

Hmmm. There was an answer with a list comprehension here, but it's disappeared.

Here:

 [i for i,x in enumerate(testlist) if x == 1]

Example:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Update:

Okay, you want a generator expression, we'll have a generator expression. Here's the list comprehension again, in a for loop:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

Now we'll construct a generator...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

and niftily enough, we can assign that to a variable, and use it from there...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

And to think I used to write FORTRAN.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • This is the best answer here, IMO. It's clear and succinct, and you actually capture the index values, so it's extensible (you can print them, pass them to another func., etc.) Only improvement is to use a generator expression for cases with many matches. http://is.gd/brzl – gotgenes Dec 13 '08 at 03:53
  • 9
    After probably 25 years of questioning functional programming, I think I'm finally getting the clue. list comprehension is da bomb. – Charlie Martin Dec 13 '08 at 18:30
  • Single word variables make it harder to comprehend your code, especially in programming examples. – mikemaccana Jan 28 '10 at 11:16
  • 15
    I presume you mean "single letter" and frankly, a longer name in this example would have no more information content. – Charlie Martin Dec 01 '10 at 19:28
  • 2
    Thanks for great answer. I think @nailer's comment might relate to the fact that you use 'i' in two different contexts in a single line in the generator example; one inside the comprehension, and the other to iterate through it. I know it threw me off for a second. – Brown May 03 '13 at 14:34
  • 1
    @CharlieMartin You use 'i' for the index rather than the item per the one common convention for single character variables. Naming the index 'index' and the item 'item' would remove ambiguity. Additionally you're replying to a parent that used 'item' and 'position' and it's good manners not to unnecessarily rename parts of the original code in your answer. – mikemaccana May 03 '13 at 14:54
  • Hm. In each case, the i outside the list comprehension or generator is exactly what's being gathered up as i inside. I'd find it confusing to have two different names for it. – Charlie Martin May 04 '13 at 15:32
  • 1
    Super syntax :o) You can easily get a command line parameter. Let there is an array of arguments: `args = ['x', '-p1', 'v1', '-p2', 'v2']`. Then the command `args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]` returns `'v1'` – Theodor Keinstein Aug 15 '14 at 11:20
194

What about the following?

print testlist.index(element)

If you are not sure whether the element to look for is actually in the list, you can add a preliminary check, like

if element in testlist:
    print testlist.index(element)

or

print(testlist.index(element) if element in testlist else None)

or the "pythonic way", which I don't like so much because code is less clear, but sometimes is more efficient,

try:
    print testlist.index(element)
except ValueError:
    pass
mmj
  • 5,514
  • 2
  • 44
  • 51
  • 6
    instead of testing before accessing, you could also just try and check for `ValueError` – kratenko Aug 18 '13 at 20:45
  • I think that he wants for find all occurrences, you seem to give only the first one. – tfv Oct 05 '17 at 08:32
  • @tfv I don't see how you can come to such conclusion since the question says "item" and not "items". – mmj Oct 08 '17 at 21:53
42

Use enumerate:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position
jfs
  • 399,953
  • 195
  • 994
  • 1,670
zdan
  • 28,667
  • 7
  • 60
  • 71
10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange instead of range as requested (see comments).

jakber
  • 3,549
  • 20
  • 20
  • replace range() with xrange() -- range() creates a list, xrange() creates a iterator. xrange() uses waaaay less memory, and the inital call is faster. – gnud Dec 13 '08 at 01:39
  • 3
    I agree for large lists in python 2 programs. Note that 'range' will still work in python 3 though (and work like xrange IIRC). 'xrange' is going the way of the dinosaurs. – jakber Dec 13 '08 at 01:44
  • 4
    Update: `xrange` is depracted in Python 3.x, as the new `range` is the old `xrange` – tim-oh Mar 13 '17 at 12:51
5

Here is another way to do this:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"
Zen
  • 15
  • 6
Phil Rankin
  • 51
  • 1
  • 1
4

Try the below:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1
3
[x for x in range(len(testlist)) if testlist[x]==1]
malekcellier
  • 177
  • 3
  • 10
1

If your list got large enough and you only expected to find the value in a sparse number of indices, consider that this code could execute much faster because you don't have to iterate every value in the list.

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

If you expect to find the value a lot you should probably just append "index" to a list and print the list at the end to save time per iteration.

  • I did some timing tests. The list comprehension technique runs 38% faster than this code. (I replaced your print statement with a outputlist.append call) – Deestan Dec 13 '08 at 16:31
  • I also did some tests with list sizes of 100000 random values between 1 and 100. The code I wrote was in some cases twice as fast. No time testing is comparable to poster's application (they must test themselves to be sure, of course). I apologize if my opinion was detrimental to this post. –  Dec 13 '08 at 17:05
0

I think that it might be useful to use the curselection() method from thte Tkinter library:

from Tkinter import * 
listbox.curselection()

This method works on Tkinter listbox widgets, so you'll need to construct one of them instead of a list.

This will return a position like this:

('0',) (although later versions of Tkinter may return a list of ints instead)

Which is for the first position and the number will change according to the item position.

For more information, see this page: http://effbot.org/tkinterbook/listbox.htm

Greetings.

seaotternerd
  • 6,298
  • 2
  • 47
  • 58
xXAngelJinXx
  • 69
  • 1
  • 7
  • 1
    Interesting idea. Since this requires importing the entire Tkinter library, though, it's not the most efficient way to solve the problem. – seaotternerd Jun 20 '13 at 22:47
  • 3
    This is such an inefficient and meandering path that I'd say it's a wrong answer, even if it somewhat addresses the question. –  Nov 09 '13 at 20:48
  • This answer has nothing to do with the question. – Cody Piersall Aug 22 '14 at 13:42
0

Why complicate things?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position
Abhishek
  • 3,337
  • 4
  • 32
  • 51
0

Just to illustrate complete example along with the input_list which has searies1 (example: input_list[0]) in which you want to do a lookup of series2 (example: input_list[1]) and get indexes of series2 if it exists in series1.

Note: Your certain condition will go in lambda expression if conditions are simple

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

output:

[0, 2, 6]
ravibeli
  • 484
  • 9
  • 30
0
l = list(map(int,input().split(",")))
num = int(input())
for i in range(len(l)):
    if l[i] == num:
        print(i)

Explanation:

Taken a list of integer "l" (separated by commas) in line 1. Taken a integer "num" in line 2. Used for loop in line 3 to traverse inside the list and checking if numbers(of the list) meets the given number(num) then it will print the index of the number inside the list.

  • Welcome to Stack Overflow! Please read How to Answer and edit your answer to contain an explanation as to why this code would actually solve the problem at hand. Always remember that you're not only solving the problem, but are also educating the OP and any future readers of this post. – Simas Joneliunas Dec 22 '22 at 04:21
-1
testlist = [1,2,3,5,3,1,2,1,6]
num = 1
for item in range(len(testlist)):
    if testlist[item] == num:
        print(item) 
Julia Meshcheryakova
  • 3,162
  • 3
  • 22
  • 42
  • 1
    test list != testlist – Vickel Dec 19 '22 at 22:26
  • It's important to not just post code, but to also include a description of what the code does and why you are suggesting it. This helps others understand the context and purpose of the code, and makes it more useful for others who may be reading the question or answer, @Shivam Raj . – DSDmark Dec 21 '22 at 15:27
-1

What about trying

list_ = ["pen", "david"]
for i in list_:
    list_.index(i)

The code literally takes each object and parses the postion of i

Additionally if you wanted to check a specific element you could try:

list_ = ["pen", "david"]
for i in list_:
    if list_.index(i) == 0:
        print(i, list_.index(i))
JawsChamp
  • 1
  • 2
-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

I guess that it's exacly what you want. ;-) 'id' will be always the index of the values on the list.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
Leonardo
  • 9
  • 2