0

Is there a standard approach to getting an item from a list but returning a default value it is is out-of-bounds?

Just as an example I have a function like this now (well, many variants of this, my newest is for reading CSV files):

def list_get_def( lst, ndx, def_val ):
  if ndx >= len(lst):
    return def_val
  return lst[ndx]
edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267

2 Answers2

3

Use a try-except block and catch the IndexError.

>>> def testFunc(lst, index):
        try:
            return lst[index]
        except IndexError:
            return "abc"


>>> testFunc([1, 2, 3], 2)
3
>>> testFunc([1, 2, 3], 9)
'abc'

A similar question here discusses why lists don't have a get method like dictionaries do.

If you really do want to use the if statement, you can do it using just a single line of code.

>>> def testFunc(lst, index):
        return lst[index] if index < len(lst) else "abc"

>>> testFunc([1, 2, 3], 2)
3
>>> testFunc([1, 2, 3], 9)
'abc'
Community
  • 1
  • 1
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
0

if you do not want to overwrite the getimtem of lists you can write a get method like dict have:

class fancyList_if(list):
    def get(self, index, default = None):
        if (index > len(self)):
            return default
        return self.__getitem__(index)

if you rarely expect to get out of bounds then you can implement this as an exce

class fancyList_except(list):
    def get(self, index, default = None):
        try:
            self.__getitem__(index)
        except IndexError:
            return default

benshmarks:

In [58]: a = fancyList_if((1,3,4,5))

In [59]: b = fancyList_except((1,3,4,5))

In [60]: %timeit a.get(2, 10)
1000000 loops, best of 3: 494 ns per loop

In [61]: %timeit a.get(10, 10)
1000000 loops, best of 3: 305 ns per loop

In [62]: %timeit b.get(2, 10)
1000000 loops, best of 3: 409 ns per loop

In [63]: %timeit b.get(10, 10)
1000000 loops, best of 3: 1.67 us per loop

break even:

500hit + 300miss = 400hit + 1700miss

hit/miss = 14

so if you expect more than 1 in 14 look up 'fails' then use the if statement else use the try/catch.

jcr
  • 1,015
  • 6
  • 18