I only want my list to have one element in it. There should be one exception raised if the list is empty and a different exception raised if the list has more than one element.
The following code accomplishes the task, but I don't think it's written as well as it should by any standards out there. Additionally, if the condition is met that the list is greater than one, I want it to print the python error "index out of range" as it does in the other condition. How can I improve upon this?
x = []
try:
if len(x) > 1:
raise Exception
else:
testVar = x[0]
except IndexError as e:
print(e)
print("list does not have any elements.")
except Exception as e:
print(e)
print("There are too many elements in the list.")
Here is a better way to write that.
def func(x):
if not x:
print("list does not have any elements.")
return None
if len(x) > 1:
print("There are too many elements in the list.")
return None
return x[0]
Note that if we omit the first three lines, then Python will automatically raise an IndexError when you refer to x[0].
Related
Suppose there are a list called 'my_list' and an int variable called 'list_index'. Basically, the list 'my_list' might change over time and hence the 'list_index' might raise 'IndexError: list index out of range'. However, I just want to make record when this error occurs since it is not that important. To avoid this error, my basic solutions currently are:
# My first way
if my_list[list_index: list_index +1]:
print('item exists')
else:
print('item does not exist')
# My second way
if -len(my_list) <= list_index < len(my_list):
print('item exists')
else:
print('item does not exist')
Except for try/except statement, are there other solutions to avoid the 'IndexError: list index out of range' error?
You can use a try-except.
a = [1,2,3]
try:
print(a[4])
except IndexError:
pass
What we can do in this scenario is we know a possible error can happen, so we encapsulate the statements where the error is prone to happen inside try and we add an except block with an error type where we define what the program should do if it encounters that error.
The general syntax for it is,
try:
# statements that can possibly cause an error
except error_type:
# what to do if an error occurred
So here the error you are mentioning is IndexError which catches the out of index exception in runtime. So a neat and pythonic way to do it is as follows.
try:
index_value = my_list[list_index]
except IndexError:
index_value = -1
print('Item index does not exist')
Use range(len(LIST)-1):
for i in range(len(LIST)-1):
if LIST[i] < LIST[i+1]:
... # you got an idea; no index error since range(len(LIST)-1)
actually you don't need to catch it, you need to avoid it by using following construction:
my_list = [1, 2, 3, 4]
for i in range(0, len(my_list)):
print(my_list[i])
len(my_list) - will prevent you to access to item that doesn't exist
I have built a max heap and trying to extract max as long as there are elements. If there isn't I'm returning an IndexError. This the code I'm trying to execute:
while True:
try:
print hp.extract_max()
except:
break
and in the extract_max() method:
def extract_max(self):
if self.size == 0:
return IndexError
item = self.items[0]
self.items[0] = self.items[self.size - 1]
self.heapify_down()
del self.items[len(self.items) - 1]
return item
However, the code is not breaking upon encountering an IndexError, rather printing it too. The while loop is not breaking.
<type 'exceptions.IndexError'>
<type 'exceptions.IndexError'>
....
it keeps printing the exception, without breaking the loop.
What's the problem?
As the other answer stated, you should raise the exception instead of return so:
if self.size == 0:
raise IndexError
I just want to add that you are catching all type of exceptions with except, you might want to change it to catch IndexError only to avoid catching other exceptions (ex: KeyboardInterrupt) as the following:
while True:
try:
print hp.extract_max()
except IndexError:
break
You should be raising an exception, not returning it. Do raise IndexError.
def FancyDivide(numbers, index):
try:
try:
denom = numbers[index]
for i in range(len(numbers)):
numbers[i] /= denom
except IndexError, e:
FancyDivide(numbers, len(numbers) - 1)
else:
print "1"
finally:
print "0"
except ZeroDivisionError, e:
print "-2"
Function Output
>>> FancyDivide([0, 2, 4], 0)
0
-2
I expect only -2 as the answer but why 0. According to me ZeroDivisionError should be caught by last except statement and therefore the answer should be -2. Confused. Please Help.
The finally block will execute regardless of if an Exception is thrown or not.
With your code throwing the exception inside the nested try, the associated finally block will execute before the outer except.
You're right, the ZeroDivisionError will be caught by the outer try block, but finally clauses are always executed before leaving their respective try block (even when an exception is raised within it).
So in your case, the inner try raises the exception, the inner finally is executed, then the outer try catches the exception.
More info here: https://docs.python.org/2/tutorial/errors.html#defining-clean-up-actions
I need to keep catching an exception while indexing a list throws a IndexError exception, for example:
l = []
while((l[3]) throws IndexError):
//Add more data to the list
l += [3]
How can I keep checking to see if the method call has thrown an exception without having nested a nested try/catch block?
It depends what you would like to extend your list with. Assuming 'None' you could do it like this:
l = []
while True:
try:
l[3] = 'item'
break
except IndexError:
l.extend([None])
print l # [None, None, None, 'item']
This is probably a very basic question, but I looked through the python documentation on exceptions and couldn't find it.
I'm trying to read a bunch of specific values from a dictionary and insert slices of these into another dictionary.
for item in old_dicts:
try:
new_dict['key1'] = item['dog1'][0:5]
new_dict['key2'] = item['dog2'][0:10]
new_dict['key3'] = item['dog3'][0:3]
new_dict['key4'] = item['dog4'][3:11]
except KeyError:
pass
Now, if Python encounters a key error at ['dog1'], it seems to abort the current iteration and go to the next item in old_dicts. I'd like it to go to the next line in the loop instead. Do I have to insert an exception instruction for each row?
Make it a function:
def newdog(self, key, dog, a, b)
try:
new_dict[key] = item[dog][a:b]
except KeyError:
pass
I didn't run the above code but something like that should work, a modularization. Or what you could do is prepare so that it checks all values and removes all values that are not in the dictionary, but that will probably be more code than an exception for each row.
for item in old_dicts:
for i, (start, stop) in enumerate([(0,5), (0,10), (0,3), (3,11)], 1):
try:
new_dict['key' + str(i)] = item['dog' + str(i)][start:stop]
except KeyError:
pass
Assuming that you know the values in the keys will be valid, why not just forgo exceptions all together and check for the keys?
for item in old_dicts:
if 'dog1' in item:
new_dict['key1'] = item['dog1'][0:5]
if 'dog2' in item:
new_dict['key2'] = item['dog2'][0:10]
if 'dog3' in item:
new_dict['key3'] = item['dog3'][0:3]
if 'dog4' in item:
new_dict['key4'] = item['dog4'][3:11]
Yes, you do. It will be messy and unpleasant to look at, but you do need an exception handler for every call.
That said, you can write your code a little differently to make life easier on yourself. Consider this:
def set_new_dict_key(new_dict, key, item, path):
try:
for path_item in path:
item = item[path_item]
except KeyError:
pass
else:
new_dict[key] = item
for item in old_dicts:
set_new_dict_key(new_dict, 'key1', item, ['dog1', slice(0, 5)])
set_new_dict_key(new_dict, 'key2', item, ['dog2', slice(0, 10)])
set_new_dict_key(new_dict, 'key3', item, ['dog3', slice(0, 3)])
set_new_dict_key(new_dict, 'key4', item, ['dog4', slice(3, 11)])
Yes, you will. Best practice is to keep your try blocks as small as possible. Only write the code you possibly expect an exception from in the try block. Note that you also have an else for the try and except statements, that only gets executed when the try ran without an exception:
try:
// code that possibly throws exception
except Exception:
// handle exception
else:
// do stuff that should be done if there was no exception