12Answers
  • 7
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

If list index exists, do X

In my program, user inputs number n, and then inputs n number of strings, which get stored in a list.

I need to code such that if a certain list index exists, then run a function.

This is made more complicated by the fact that I have nested if statements about len(my_list).

Here's a simplified version of what I have now, which isn't working:

n = input ("Define number of actors: ")

count = 0

nams = []

while count < n:
    count = count + 1
    print "Define name for actor ", count, ":"
    name = raw_input ()
    nams.append(name)

if nams[2]: #I am trying to say 'if nams[2] exists, do something depending on len(nams)
    if len(nams) > 3:
        do_something
    if len(nams) > 4
        do_something_else

if nams[3]: #etc.

Could it be more useful for you to use the length of the list len(n) to inform your decision rather than checking n[i] for each possible length?

  • 157
Reply Report
      • 2
    • This doesn't account for negative indexes. The best way I know is try / except IndexError, but it'd be nice to have a concise way to get a bool
    • In Python negative indexes on lists just count backwards from the end of the list. So they could not exist in a way that impacts the length of the list.
    • Yep. Upon reviewing the code, my set-up was completely superfluous; len(n) accomplished everything I needed. Thanks for a point in the right direction.

I need to code such that if a certain list index exists, then run a function.

This is the perfect use for a try block:

ar=[1,2,3]

try:
    t=ar[5]
except IndexError:
    print('sorry, no 5')   

# Note: this only is a valid test in this context 
# with absolute (ie, positive) index
# a relative index is only showing you that a value can be returned
# from that relative index from the end of the list...

However, by definition, all items in a Python list between 0 and len(the_list)-1 exist (i.e., there is no need for a try, except if you know 0 <= index < len(the_list)).

You can use enumerate if you want the indexes between 0 and the last element:

names=['barney','fred','dino']

for i, name in enumerate(names):
    print(i + ' ' + name)
    if i in (3,4):
        # do your thing with the index 'i' or value 'name' for each item...

If you are looking for some defined 'index' thought, I think you are asking the wrong question. Perhaps you should consider using a mapping container (such as a dict) versus a sequence container (such as a list). You could rewrite your code like this:

def do_something(name):
    print('some thing 1 done with ' + name)

def do_something_else(name):
    print('something 2 done with ' + name)        

def default(name):
    print('nothing done with ' + name)     

something_to_do={  
    3: do_something,        
    4: do_something_else
    }        

n = input ("Define number of actors: ")
count = 0
names = []

for count in range(n):
    print("Define name for actor {}:".format(count+1))
    name = raw_input ()
    names.append(name)

for name in names:
    try:
        something_to_do[len(name)](name)
    except KeyError:
        default(name)

Runs like this:

Define number of actors: 3
Define name for actor 1: bob
Define name for actor 2: tony
Define name for actor 3: alice
some thing 1 done with bob
something 2 done with tony
nothing done with alice

You can also use .get method rather than try/except for a shorter version:

>>> something_to_do.get(3, default)('bob')
some thing 1 done with bob
>>> something_to_do.get(22, default)('alice')
nothing done with alice
  • 84
Reply Report
      • 1
    • try block? I am a beginner in Python but this seems like a big no no in programming...exceptions for flow control? Exception should be for things we cannot control right?
      • 1
    • The sentence 'all indices in a Python list between 0 and len(list)' is absolutely wrong. Let's say there's a list x = [1, 2, 3] which len_x = 3. There is no such index as 3. The sentence should have been: 'all indices in a Python list between 0 and len(list) - 1'.
      • 1
    • @LiorMagen: You are right and I edited it. That is kinda harsh to down vote a fairly popular post for such a pedantic error. A simple comment would suffice.
      • 1
    • I'll point out that sticking things inside a try does not tell you if the index exists just if it is fetchable - take -1 - that index doesn't really exist but a value would be returned.

I need to code such that if a certain list index exists, then run a function.

You already know how to test for this and in fact are already performing such tests in your code.

The valid indices for a list of length n are 0 through n-1 inclusive.

Thus, a list has an index i if and only if the length of the list is at least i + 1.

  • 6
Reply Report
    • Yep, I had the tools to solve my problem, just wasn't applying them clearly. Thanks for a point in the right direction.
    • Thanks for this, especially the last sentence, which is an important property of Python lists that make them different from JavaScript arrays and other similar constructs.

Using the length of the list would be the fastest solution to check if an index exists:

def index_exists(ls, i):
    return (0 <= i < len(ls)) or (-len(ls) <= i < 0)

This also tests for negative indices, and most sequence types (Like ranges and strs) that have a length.

If you need to access the item at that index afterwards anyways, it is easier to ask forgiveness than permission, and it is also faster and more Pythonic. Use try: except:.

try:
    item = ls[i]
    # Do something with item
except IndexError:
    # Do something without the item

This would be as opposed to:

if index_exists(ls, i):
    item = ls[i]
    # Do something with item
else:
    # Do something without the item
  • 6
Reply Report

You can try something like this

list = ["a", "b", "C", "d", "e", "f", "r"]

for i in range(0, len(list), 2):
    print list[i]
    if len(list) % 2 == 1 and  i == len(list)-1:
        break
    print list[i+1];
  • 1
Reply Report

Oneliner:

do_X() if len(your_list) > your_index else do_something_else()  

Full example:

In [10]: def do_X(): 
    ...:     print(1) 
    ...:                                                                                                                                                                                                                                      

In [11]: def do_something_else(): 
    ...:     print(2) 
    ...:                                                                                                                                                                                                                                      

In [12]: your_index = 2                                                                                                                                                                                                                       

In [13]: your_list = [1,2,3]                                                                                                                                                                                                                  

In [14]: do_X() if len(your_list) > your_index else do_something_else()                                                                                                                                                                      
1

Just for info. Imho, try ... except IndexError is better solution.

  • 1
Reply Report

A lot of answers, not the simple one.

To check if a index 'id' exists at dictionary dict:

dic = {}
dic['name'] = "joao"
dic['age']  = "39"

if 'age' in dic

returns true if 'age' exists.

  • -3
Reply Report
      • 2
    • Not a good answer to the question. The question was about lists, not dictionaries. What you proposed can't be done in cases such as this: ["joao", 39]

Trending Tags