Reputation: 1075
I'm a bit stumped here. Here's a piece of Python code:
try:
if parse[index+1][0] != "5":
individual_services+=[individual_services_cur]
individual_services_cur=[]
except IndexError:
warning("Reached end of file. No next element")
individual_services+=[individual_services_cur]
individual_services_cur=[]
Basically I want these two actions (addition of individual_services_cur
list to individual_services
list and clearing of individual_services_cur
list) to take place either if the next element in parse
is not "5" or if it doesn't exist (basically it is the end of file).
I am wondering if there is a more elegant (maybe even, as they say, "pythonic") way to write this code, for example, without the need to write these two actions twice. I couldn't think of any good solution with finally
or else
statements, and it seems that I cannot get rid of try
statement because once the end of file is reached, the IndexError
exception is inevitably raised.
Upvotes: 4
Views: 16841
Reputation: 45231
Another idea:
update_i_s = True
try:
update_i_s= parse[index+1][0] != "5"
except IndexError:
warning("Reached end of file. No next element")
finally:
if update_i_s:
individual_services.append([individual_services_cur]) if flag
individual_services_cur=[]
flag=True
is only needed for the case that there is only one line in the file, and only needs to be set once at the beginning (so don't go putting it inside any loops).
EDIT:
By the way, if there is a possibility the finally
block could fail, you might want to do something like this:
try:
try:
update_i_s= parse[index+1][0] != "5"
except IndexError:
warning("Reached end of file. No next element")
finally:
if update_i_s:
individual_services.append([individual_services_cur]) if flag
individual_services_cur=[]
except Exception:
warning("failed to update individual_services")
raise
Upvotes: 2
Reputation: 45231
Or thinking outside the box a bit:
if index + 1 not in (index for index, value in enumerate(parse) if value[0] == '5'):
individual_services+=[individual_services_cur]
individual_services_cur=[]
Where (index for index, value in enumerate(parse) if value[0] == '5')
is a generator that yields the line number of each line that has a '5' as the first character. It is equivalent to this:
def has_5s(p):
'''Yield line numbers that begin with a 5'''
for index, line in enumerate(p):
yield index if line[0] == '5'
if index + 1 not in has_5s(parse):
individual_services+=[individual_services_cur]
individual_services_cur=[]
You are simply checking to see if the following line number (line + 1
) is one of these line numbers yielded by the generator. Since enumerate
and the generator itself are lazy this should be very fast.
Upvotes: 0
Reputation: 56634
How about
last = len(parse) - 1
if index == last or parse[index + 1][0] != "5":
individual_services.append(individual_services_cur)
individual_services_cur = []
Upvotes: 0
Reputation: 41
You can use an intermediate variable to perform the checks you need.
try:
value_to_check = parse[index+1][0]
except IndexError:
warning("Reached end of file. No next element")
value_to_check = None
finally:
if value_to_check != "5":
individual_services+=[individual_services_cur]
individual_services_cur=[]
Upvotes: 3
Reputation: 59113
You could assign a variable in both cases and then check it once.
badstuff = False
try:
if parse[index+1][0] != "5":
badstuff = True
except IndexError:
warning("Reached end of file. No next element")
badstuff = True
if badstuff:
individual_services+=[individual_services_cur]
individual_services_cur=[]
If it suits you, you could put the if badstuff:
in a finally
block, depending on what the rest of your code is doing.
Alternatively, put the individual_services
stuff in a function, and call it in both places.
Upvotes: 1