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?
5 Answers 5
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.
Comments
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
Comments
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]
3 Comments
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)])
Comments
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
key2missing, or shouldkey2be mapped to some default value (perhapsNone)?