Home > database >  Iterating over a list of lists and checking for a condition Python
Iterating over a list of lists and checking for a condition Python

Time:01-17

I have a data object that I created by manipulating a larger data set. It is a list of lists where at the highest level is day of week (1-7 but for brevity I only included the first day), and the second level is the times within each day. The object looks like this:

act_all_fun = [[[datetime.time(0, 0), 254, 'F37', 'd1'],
                [datetime.time(2, 0), 254, 'F7', 'd1'],
                [datetime.time(5, 0), 254, 'F17', 'd1'],
                [datetime.time(6, 30), 254, 'F37', 'd1'],
                [datetime.time(7, 0), 15, 'F37', 'd1'],
                [datetime.time(10, 0), 17, 'F37', 'd0'],
                [datetime.time(12, 0), 19, 'F37', 'd0'],
                [datetime.time(21, 0), 15, 'F7', 'd1'],
                [datetime.time(23, 0), 254, 'F37', 'd1']],
               [[datetime.time(0, 0), 254, 'F37', 'd1'],
                [datetime.time(1, 30), 254, 'F', 'd1'],
                [datetime.time(5, 0), 2, 'F7', 'd1'],
                [datetime.time(6, 30), 2, 'F37', 'd0'],
                [datetime.time(8, 0), 7, 'F37', 'd0'],
                [datetime.time(9, 15), 11, 'F', 'd0'],
                [datetime.time(10, 15), 15, 'F', 'd0'],
                [datetime.time(15, 30), 5, 'F37', 'd0'],
                [datetime.time(16, 15), 6, 'F', 'd0'],
                [datetime.time(19, 30), 9, 'F37', 'd0'],
                [datetime.time(23, 0), 254, 'F37', 'd1']]]

I want iterate over each specific list (at the time level) within act_all_fun and:

  1. Check if the second element of each is equal to 254: a. If true, see how many unique third elements (e.g. 'F' or 'F7' or 'F17'. etc.): For each unique third element, subtract 1 from 254
  2. If the second element is not equal to 254: a. For example, if the second element is equal to 15: Check any other element that is 15 and see how many unique values there are for the third element when it is 15 as the second element.For each unique element add 30 to the second element.

For example, the desired output would be:

    act_all_fun = [[[datetime.time(0, 0), 254, 'F37', 'd1'],
                [datetime.time(2, 0), 253, 'F7', 'd1'],
                [datetime.time(5, 0), 252, 'F17', 'd1'],
                [datetime.time(6, 30), 254, 'F37', 'd1'],
                [datetime.time(7, 0), 15, 'F37', 'd1'],
                [datetime.time(10, 0), 17, 'F37', 'd0'],
                [datetime.time(12, 0), 19, 'F37', 'd0'],
                [datetime.time(21, 0), 45, 'F7', 'd1'],
                [datetime.time(23, 0), 254, 'F37', 'd1']],
               [[datetime.time(0, 0), 254, 'F37', 'd1'],
                [datetime.time(1, 30), 251, 'F', 'd1'],
                [datetime.time(5, 0), 2, 'F7', 'd1'],
                [datetime.time(6, 30), 2, 'F37', 'd0'],
                [datetime.time(8, 0), 7, 'F37', 'd0'],
                [datetime.time(9, 15), 11, 'F', 'd0'],
                [datetime.time(10, 15), 75, 'F', 'd0'],
                [datetime.time(15, 30), 5, 'F37', 'd0'],
                [datetime.time(16, 15), 6, 'F', 'd0'],
                [datetime.time(19, 30), 9, 'F37', 'd0'],
                [datetime.time(23, 0), 254, 'F37', 'd1']]]

For ease of reference, check the output at: a- day 1 times: (0,0)/(2,0), (5,0)/(6,30)/(21,0) b- day 2 times: (1,30)/(10,15)

I tried something like this:

for day in act_all_fun:
for act in day:
    if act[1] in range(240,255) and act[2] not in [x[2] for x in day if x != act]:
        act[1] = act[1] - 1

But that didn't yield the results I expected.

I have tried multiple different things from flattening the list to putting it into a dataframe but to no avail. I also tried to be as clear as possible but realize that I may have fallen short. If you need any clarification please let me know.

CodePudding user response:

Alright, After much work and trying multiple iterations, conceptually, this problem could be solved by: a- Flattening the list of lists b- Creating pairs of items which we want to compare c- Indexing the matches we get d- Processing (i.e. manipulating the values we need) the items that meet the established conditions.

Here is the code, hoping it helps anyone else with this, or any other derivative of this problem:

#flattening the list for ease of operation
def flatten(input_list):
  flat_list = []
  for sublist in input_list:
    for item in sublist:
      flat_list.append(item)
  return flat_list
act_flt = flatten(flatten(act_all_fun))

# Creating unique pattern-based actions
unq_act = []
idx_act = []
for i in range(len(act_flt)):
    if isinstance(act_flt[i], int) and act_flt[i] != 254:
        unq_act.append([act_flt[i], act_flt[i 1]])
        idx_act.append(i)
unique_second_elements = []
for item in new_list:
    if item[1] not in unique_second_elements:
        unique_second_elements.append(item[1])
        
for second_element in unique_second_elements:
    for item in unq_act:
        if item[1] == second_element:
            item[0]  = (unique_second_elements.index(second_element) * 30)
            
# Creating unique free pattern-based actions
unq_free = []
idx_free = []
for i in range(len(act_flt)):
    if isinstance(act_flt[i], int) and act_flt[i] == 254:
        unq_free.append([act_flt[i], act_flt[i 1]])
        idx_free.append(i)
unique_second_elements = []
for item in unq_free:
    if item[1] not in unique_second_elements:
        unique_second_elements.append(item[1])
        
for second_element in unique_second_elements:
    for item in unq_free:
        if item[1] == second_element:
            item[0]  = (unique_second_elements.index(second_element) - 2)

Now to process the previous outputs:

dow1 = len(act_all_fun[0])*4 -1
dow2 = len(act_all_fun[1])*4 
dow3 = len(act_all_fun[2])*4 
dow4 = len(act_all_fun[3])*4 
dow5 = len(act_all_fun[4])*4 
dow6 = len(act_all_fun[5])*4 
dow7 = len(act_all_fun[6])*4 

for i in idx_act:
    if 0<=i<=dow1:
        day = 0
        act_tmp = i//4 #finding the action entry
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    elif dow1<i<=(dow1 dow2):
        day = 1
        act_tmp = (i-dow1)//4 #finding the action entry
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    elif (dow1 dow2)<i<=(dow1 dow2 dow3):
        day = 2
        act_tmp = (i-(dow1 dow2))//4
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    elif dow1 dow2 dow3<i<=(dow1 dow2 dow3 dow4):
        day = 3
        act_tmp = (i-(dow1 dow2 dow3))//4
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    elif dow1 dow2 dow3 dow4<i<=(dow1 dow2 dow3 dow4 dow5):
        day = 4
        act_tmp = (i-(dow1 dow2 dow3 dow4))//4
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    elif dow1 dow2 dow3 dow4 dow5<i<=(dow1 dow2 dow3 dow4 dow5 dow6):
        day = 5
        act_tmp = (i-(dow1 dow2 dow3 dow4 dow5))//4
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)
    else:
        day = 6
        act_tmp = (i-(dow1 dow2 dow3 dow4 dow5 dow6))//4
        act_all_fun[day][act_tmp][1] = unq_act[idx_act.index(i)][0]
        print(i)

for j in idx_free:
    if 0<=j<=dow1:
        day = 0
        act_tmp = j//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    elif dow1<j<=(dow1 dow2):
        day = 1
        act_tmp = (j-dow1)//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    elif dow1 dow2<j<=(dow1 dow2 dow3):
        day = 2
        act_tmp = (j-(dow1 dow2))//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    elif dow1 dow2 dow3<j<=(dow1 dow2 dow3 dow4):
        day = 3
        act_tmp = (j-(dow1 dow2 dow3))//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    elif dow1 dow2 dow3 dow4<j<=(dow1 dow2 dow3 dow4 dow5):
        day = 4
        act_tmp = (j-(dow1 dow2 dow3 dow4))//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    elif dow1 dow2 dow3 dow4 dow5<j<=(dow1 dow2 dow3 dow4 dow5 dow6):
        day = 5
        act_tmp = (j-(dow1 dow2 dow3 dow4 dow5))//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)
    else:
        day = 6
        act_tmp = (j-(dow1 dow2 dow3 dow4 dow5 dow6))//4
        act_all_fun[day][act_tmp][1] = unq_free[idx_free.index(j)][0]
        print(j)

Feel free to extract what you need from this.

  • Related