0

I started with this list of dictionaries.

[{'allow_day_and_time': {'day': 'Monday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Tuesday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Wednesday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Thursday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Friday', 'start': 9, 'end': 18}}]

I applied this.

index = 0
    while index < len(availability_constraints):
        for key in availability_constraints[index]:
            print(availability_constraints[index][key])
        index += 1

results in

{'day': 'Monday', 'start': 9, 'end': 18}
{'day': 'Tuesday', 'start': 9, 'end': 18}
{'day': 'Wednesday', 'start': 9, 'end': 18}
{'day': 'Thursday', 'start': 9, 'end': 18}
{'day': 'Friday', 'start': 9, 'end': 18}

It's possible that I could be returned multiple start and end vales for any of days returned for example Monday start 9, finish 11, Monday Start 13, finish 18.

What I'm struggling with is how to get the start and finish time for the days retuned keeping in mind I might be returned multiple start and end times for the same day.

Any pointers would be a big help.

Lee
  • 87
  • 11
  • What will the input look like if you have multiple entries for a single day? Are you doing anything other than just printing out the entries? – chuckx Jun 02 '18 at 04:21

2 Answers2

1

I assume your complete data may look somehow like this:

[{'allow_day_and_time': {'day': 'Monday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Tuesday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Wednesday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Thursday', 'start': 9, 'end': 18}}, 
{'allow_day_and_time': {'day': 'Friday', 'start': 9, 'end': 18}},
{'allow_day_and_time': {'day': 'Monday', 'start': 13, 'end': 21}}, 
{'allow_day_and_time': {'day': 'Tuesday', 'start': 13, 'end': 21}}, 
{'allow_day_and_time': {'day': 'Wednesday', 'start': 13, 'end': 21}}, 
{'allow_day_and_time': {'day': 'Thursday', 'start': 13, 'end': 21}}, 
{'allow_day_and_time': {'day': 'Friday', 'start': 13, 'end': 21}}]

Since your data is a list of dictionary items, you can access the dictionary simply by supplying the key within [] bracket, or, you can retrieve the key and value using dictionary.iteritems()

Iterating with dictionary.iteritems()

In [  ]: index = 0
    ...: while index < len(availability_constraints):
    ...:     for key, value in availability_constraints[index].iteritems():
    ...:         print(key, value)
    ...:     index += 1
    ...: 
('allow_day_and_time', {'start': 9, 'end': 18, 'day': 'Monday'})
('allow_day_and_time', {'start': 9, 'end': 18, 'day': 'Tuesday'})
('allow_day_and_time', {'start': 9, 'end': 18, 'day': 'Wednesday'})
('allow_day_and_time', {'start': 9, 'end': 18, 'day': 'Thursday'})
('allow_day_and_time', {'start': 9, 'end': 18, 'day': 'Friday'})
('allow_day_and_time', {'start': 13, 'end': 21, 'day': 'Monday'})
('allow_day_and_time', {'start': 13, 'end': 21, 'day': 'Tuesday'})
('allow_day_and_time', {'start': 13, 'end': 21, 'day': 'Wednesday'})
('allow_day_and_time', {'start': 13, 'end': 21, 'day': 'Thursday'})
('allow_day_and_time', {'start': 13, 'end': 21, 'day': 'Friday'})

Let's say you are querying the start of Monday, you can use if and == operator to check if the value of that particular element of the list is referring to Monday:

In [  ]: index = 0
    ...: while index < len(availability_constraints):
    ...:     for key, value in availability_constraints[index].iteritems():
    ...:         if value['day'] == 'Monday':
    ...:             print("Start: {:>4}, Finish: {:>4}".format(value['start'], value['end']))
    ...:     index += 1
    ...: 
Start:    9, Finish:   18
Start:   13, Finish:   21

Iterating with [] and supplying hardcoded key

Another more straightforward/hardcoded, which may not be the best programming practice, is shown below:

In [  ]: for a_day in availability_constraints:
    ...:     if a_day['allow_day_and_time']['day'] == 'Monday':
    ...:         print("Start: {:>4}, Finish: {:>4}".format(
    ...:          a_day['allow_day_and_time']['start'],
    ...:          a_day['allow_day_and_time']['end']))
    ...:         
    ...:         
Start:    9, Finish:   18
Start:   13, Finish:   21

We can also introduce indirection for better maintenance:

In [  ]: key = 'allow_day_and_time'
    ...: target_day = 'Monday'
    ...: begin = 'start'
    ...: finish = 'end'
    ...: for a_day in availability_constraints:
    ...:     if a_day[key]['day'] == target_day:
    ...:         print("Start: {:>4}, Finish: {:>4}".format(
    ...:          a_day[key][begin],
    ...:          a_day[key][finish]))
    ...:         
    ...:         
Start:    9, Finish:   18
Start:   13, Finish:   21

Conclusion: The pythonic way

Check this link for pythonic string formatting

In [  ]: for a_day in availability_constraints:
    ...:     for key, value in a_day.iteritems():
    ...:         if value['day'] == 'Monday':
    ...:             print("Start: {:>4}, Finish: {:>4}".format(value['start'], value['end']))
Start:    9, Finish:   18
Start:   13, Finish:   21

Which programming style is the best? Well, I'm pretty opinionated myself, so I believe it depends on your preference unless you want this program to be optimized :D

Toto Lele
  • 394
  • 2
  • 13
0

You can use itertools.groupby to find all days associated with common start and end values:

import itertools
def time_key(x:dict):
  _d = x['allow_day_and_time']
  return _d['start'], _d['end']

d = [{'allow_day_and_time': {'day': 'Monday', 'start': 9, 'end': 18}}, {'allow_day_and_time': {'day': 'Tuesday', 'start': 9, 'end': 18}}, {'allow_day_and_time': {'day': 'Wednesday', 'start': 9, 'end': 18}}, {'allow_day_and_time': {'day': 'Thursday', 'start': 9, 'end': 18}}, {'allow_day_and_time': {'day': 'Friday', 'start': 9, 'end': 18}}, {'allow_day_and_time': {'day': 'Monday', 'start': 13, 'end': 21}}, {'allow_day_and_time': {'day': 'Tuesday', 'start': 13, 'end': 21}}, {'allow_day_and_time': {'day': 'Wednesday', 'start': 13, 'end': 21}}, {'allow_day_and_time': {'day': 'Thursday', 'start': 13, 'end': 21}}, {'allow_day_and_time': {'day': 'Friday', 'start': 13, 'end': 21}}]
new_d = [{'start':_s, 'end':_e, 'days':[i['allow_day_and_time']['day'] for i in b]} for [_s, _e], b in itertools.groupby(sorted(d, key=time_key), key=time_key)]

Output:

[{'start': 9, 'end': 18, 'days': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']}, {'start': 13, 'end': 21, 'days': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']}]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102