tags:

views:

194

answers:

6
a=['123','2',4]
b=a[4] or 'sss'
print b

I want to get a default value when the list index is out of range (here: 'sss').

How can I do this?

+8  A: 

In the Python spirit of "ask for forgiveness, not permission", here's one way:

try:
    b = a[4]
except IndexError:
    b = 'sss'
Thomas
any simple way ??
zjm1126
If you want a one-liner, put that into a small helper function.
Matti Virkkunen
@zjm: this *is* a simple way
Eli Bendersky
Is it necessary to span into 3 answers?
KennyTM
@KennyTM: They are three different options. I figured, this way the best answer could be voted to the top and the crappy ones disappear into oblivion. It was not intended as rep-baiting, and is actually accepted practice: http://meta.stackoverflow.com/questions/21761/can-i-answer-a-question-multiple-times
Thomas
@zjm1126: there's a shorter way if you can use a dict instead of a list. See my answer.
Goose Bumper
+1  A: 
try:
    b = a[4]
except IndexError:
    b = 'sss'

A cleaner way (only works if you're using a dict):

b = a.get(4,"sss") # exact same thing as above

Here's another way you might like (again, only for dicts):

b = a.setdefault(4,"sss") # if a[4] exists, returns that, otherwise sets a[4] to "sss" and returns "sss"
Goose Bumper
You should define the exception for `except:`. For example your exception is also triggered when variable `a` is not defined.
zoli2k
@Goose: empty `except` is evil. It's far better to say `except IndexError`
Eli Bendersky
@shakov, @Eli Bendersky: you're right. Fixed.
Goose Bumper
A: 

Using try/catch?

try:
    b=a[4]
except IndexError:
    b='sss'
zoli2k
+1  A: 

In the non-Python spirit of "ask for permission, not forgiveness", here's another way:

b = a[4] if len(a) > 4 else 'sss'
Thomas
didn't know this construct.. +1
redShadow
A: 

You could also define a little helper function for these cases:

def default(x, e, y):
    try:
        return x()
    except e:
        return y

It returns the return value of the function x, unless it raised an exception of type e; in that case, it returns the value y. Usage:

b = default(lambda: a[4], IndexError, 'sss')

Edit: Made it catch only one specified type of exception.

Suggestions for improvement are still welcome!

Thomas
@Thomas: IMHO it's inelegant, and the all-catching `except` is worrisome
Eli Bendersky
There's a discussion on the mailing list about a construct like this: http://mail.python.org/pipermail/python-dev/2009-August/091039.html
Thomas
+1  A: 

I’m all for asking permission (i.e. I don’t like the tryexcept method). However, the code gets a lot cleaner when it’s encapsulated in a method:

def get_at(array, index, default):
    if index < 0: index += len(array)
    if index < 0: raise IndexError('list index out of range')
    return array[index] if index < len(a) else default

b = get_at(a, 4, 'sss')
Konrad Rudolph
`mylist[-1]` should just get the last element, but your "asking permission" `get_at` code _doesn't_ behave like that. This shows one of the many reasons "asking permission" is just the wrong philosophy: what you're checking might not match what the system would do. I.e., not only are you systematically trying to duplicate work the system does for you, but you can easily get that extra, duplicated work wrong. "asking forgiveness" is **much** better.
Alex Martelli
@Alex: good catch, didn’t think of that. Python’s poweful list slices syntax makes this slightly more complicated … *however*, I don’t agree with your extrapolation from this special case that “asking forgiveness” in general is good. I’m of course biased since I’m a huge proponent of static typing. But anyway, that’s just the wrong conclusion. A better conclusion would be that my requirement analysis was insufficient (*and* perhaps that there’s no good way to get the internal behaviour in a modifiable way without either code duplication or error triggering. Which points to a bad API).
Konrad Rudolph
You could get away with it if you do `def get_at(array, index, default): try: return array[index] except IndexError: return default`
voyager
@voyager: I’m aware of that. But as I said in the very first sentence, I’m opposed to deliberately triggering exceptions. I prefer explicitness over implicitness since it reduces sources of confusion (and hence errors) and this means keeping tab on what my methods can and cannot do.
Konrad Rudolph