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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
In the Python spirit of “ask for forgiveness, not permission”, here’s one way:
try:
b = a[4]
except IndexError:
b = 'sss'
Method 2
In the non-Python spirit of “ask for permission, not forgiveness”, here’s another way:
b = a[4] if len(a) > 4 else 'sss'
Method 3
In the Python spirit of beautiful is better than ugly
Code golf method, using slice and unpacking (not sure if this was valid 4 years ago, but it is in python 2.7 + 3.3)
b,=a[4:5] or ['sss']
Nicer than a wrapper function or try-catch IMHO, but intimidating for beginners.
using slicing without unpacking:
b = a[4] if a[4:] else 'sss'
or, if you have to do this often, and don’t mind making a dictionary
d = dict(enumerate(a)) b=d.get(4,'sss')
Method 4
another way:
b = (a[4:]+['sss'])[0]
Method 5
You could create your own list-class:
class MyList(list):
def get(self, index, default=None):
return self[index] if len(self) > index else default
You can use it like this:
>>> l = MyList(['a', 'b', 'c']) >>> l.get(1) 'b' >>> l.get(9, 'no') 'no'
Method 6
For a common case where you want the first element, you can do
next(iter([1, 2, 3]), None)
I use this to “unwrap” a list, possibly after filtering it.
next((x for x in [1, 3, 5] if x % 2 == 0), None)
or
cur.execute("SELECT field FROM table")
next(cur.fetchone(), None)
Method 7
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!
Method 8
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"
Method 9
I’m all for asking permission (i.e. I don’t like the try…except 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')
Method 10
If you are looking for a maintainable way of getting default values on the index operator I found the following useful:
If you override operator.getitem from the operator module to add an optional default parameter you get identical behaviour to the original while maintaining backwards compatibility.
def getitem(iterable, index, default=None):
import operator
try:
return operator.getitem(iterable, index)
except IndexError:
return default
Method 11
If you are looking for a quick hack for reducing the code length characterwise, you can try this.
a=['123','2',4]
a.append('sss') #Default value
n=5 #Index you want to access
max_index=len(a)-1
b=a[min(max_index, n)]
print(b)
But this trick is only useful when you no longer want further modification to the list
Method 12
Since this is a top google hit, it’s probably also worth mentioning that the standard “collections” package has a “defaultdict” which provides a more flexible solution to this problem.
You can do neat things, for example:
twodee = collections.defaultdict(dict) twodee["the horizontal"]["the vertical"] = "we control"
Read more: http://docs.python.org/2/library/collections.html
Method 13
Using try/catch?
try:
b=a[4]
except IndexError:
b='sss'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0