Continually catch exception in python - python

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']

Related

What is the proper way to write this exception handling?

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].

How to avoid 'IndexError: list index out of range' error?

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

exception raised inside of a map() inside of a try-expect not handled by try-except

Anyone understand how to handle an error inside of a map()? I would like to be able to handle this kind of error without the program crashing.
def add_one(val):
raise Exception('My error!')
return val+1
values = [1,2,3,4]
# Does not work
try:
new_values = map(add_one, values)
except:
new_values = []
print(list(new_values)) # Raises an Exception: My error!
# Works
try:
new_values = []
for x in values:
new_values.append(add_one(x))
except:
new_values = []
print(new_values) # Returns []
map is lazy - it doesn't actually consume the data until necessary.
So the two examples you've provided aren't equivalent.

Python Catching Exception But Printing Them

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.

Exception handling without breaking, Python

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

Categories

Resources