Python algorithm which should be executed in python style?

Given the input text array

input_array = [ 'JUNK', 'Mon', 'JUNK', '10am', 'JUNK', '-', ' 5pm', '6pm', '-', '9pm', 'JUNK', 'Tue', '10am', '-', 'JUNK', '5pm' ] 

should convert to json

 [ { "weekday_name": "monday", "starting_time": "10am", "ending_time": "5pm" }, { "weekday_name": "monday", "starting_time": "6pm", "ending_time": "10pm" }, ... ] 

Although this is a simple algorithm, I am forced to create temporary variables that are usually considered non-pythons .

Code with ugly temporary variables

 import pprint input_array = ['JUNK','Mon','JUNK','10am','JUNK','-','5pm','6pm','-','9pm','JUNK','Tue','10am','-','JUNK','5pm'] business_hours = [] start_hours = None end_hours = None current_day = None dash_found = False days_of_the_week = {} days_of_the_week['Mon'] = 'monday' days_of_the_week['Tue'] = 'tuesday' days_of_the_week['Wed'] = 'wednesday' days_of_the_week['Thu'] = 'thursday' days_of_the_week['Fri'] = 'friday' days_of_the_week['Sat'] = 'saturday' days_of_the_week['Sun'] = 'sunday' for x in input_array: if x in days_of_the_week: current_day = days_of_the_week[x] elif x[0].isdigit() and dash_found == False: starting_time = x elif x == '-': dash_found = True elif x[0].isdigit() and dash_found == True: ending_time = x business_hours.append({"weekday_name":current_day,"starting_time":starting_time,"ending_time":ending_time}) dash_found = False pprint.pprint(business_hours) 

Can I make the code less ugly and do the same without creating many temporary variables in python?

+5
source share
2 answers

Since your data is always in the same order:

 # Here you remove all the cells in your array which are not a day of the week # or a time (not the call to "list" before filter object are not indexable in Python 3+) data = list(filter(lambda x: x in days_of_the_week or x[0].isdigit(), input_array)) while data: # Get the first item available and remove it curday = days_of_the_week[data.pop(0)] # For each couple (start, end), add an item to business_hours while data and data[0][0].isdigit(): business_hours.append({ 'weekday_name': curday, 'starting_time': data[0], 'ending_time': data[1] }) data = data[2:] 

Of course there are many ways to do this, you'll probably stick with the curday variable, since you need to remember it (you could use the last entry in business_hours , but it would be more ugly, IMO).

Edit: Someone suggested that editing the list message is not required. Since I don’t know which version of python you are using, I am assuming python 3.0 , in which case list is required ( filter are generator in python 3.0 ), so they cannot be indexed). If you are using python 2.0 , list may not be necessary.


For the pleasure of this, here is one liner using abbreviations (do you need to talk about this?):

 from functools import reduce # Okay, okay, 2 lines! reduce (lambda r, x: r + [{'weekday_name': days_of_the_week[x]}] if x in days_of_the_week else r + [{'weekday_name': r[-1]['weekday_name'], 'starting_time': x}] if len(r[-1]) == 3 else (r[-1].update({'starting_time': x}), r)[1] if len(r[-1]) == 1 else (r[-1].update({'ending_time': x}), r)[1], filter(lambda x: x in days_of_the_week or x[0].isdigit(), input_array), []) 
+6
source

The following script is quite forgiving in terms of input, so I don't see the path around a couple of variables.

I added another test case for Sunday with 3 times a week and several different JUNKs.

 import pprint input_array = [ 'JUNK', 'Mon', 'JUNK', '10am', 'JUNK', '-', ' 5pm', '6pm', '-', '9pm', 'JUNK', 'Tue', '10am', '-', 'JUNK', '5pm', "Sun ", " 8am", "- ", "JUNK", "MORE JUNK", " 9pm", "10am ", "-", " 1pm", " 6pm", "-", "8pm"] days_of_the_week = {'mon' : 'monday', 'tue' : 'tuesday', 'wed' : 'wednesday', 'thu' : 'thursday', 'fri' : 'friday', 'sat' : 'saturday', 'sun' : 'sunday'} business_hours = [] start = None for entry in input_array: entry = entry.strip().lower() if entry in days_of_the_week: current_day = days_of_the_week[entry] elif entry[0].isdigit() and start: business_hours.append({"weekday_name": current_day, "starting_time": start, "ending_time": entry}) start = None elif entry[0].isdigit(): start = entry pprint.pprint(business_hours) 

The output of the following result:

 [{'ending_time': '5pm', 'starting_time': '10am', 'weekday_name': 'monday'}, {'ending_time': '9pm', 'starting_time': '6pm', 'weekday_name': 'monday'}, {'ending_time': '5pm', 'starting_time': '10am', 'weekday_name': 'tuesday'}, {'ending_time': '9pm', 'starting_time': '8am', 'weekday_name': 'sunday'}, {'ending_time': '1pm', 'starting_time': '10am', 'weekday_name': 'sunday'}, {'ending_time': '8pm', 'starting_time': '6pm', 'weekday_name': 'sunday'}] 
0
source

All Articles