rharper
rharper

Reputation: 565

Python go back through list of lists to see if value exists

Lets say I have a 2D list:

     #0 #1   #start #end   #holiday
lst=[[1,'a', False, False, False],
     [3,'b', False, False, False],
     [7,'c', False, True,  False],
     [0,'c', False, False, True],
     [13,'d',True,  False, False],
     [21,'e',False, False, False],
     [31,'f',False, False, False]]

(n.b. this is just a very simplified version of a larger list involving times. Start would be the start of the week and End is the end of the week, which are boolean values)

What I have so far, is that it goes through the list, and if start is False, it calculates the difference between the current #0 value and the previous rows #0 value, and appends it to the current row in the format diff, D.

If start is true, it then looks back to the previous rows End value, and if it is true it calculates the difference between the current row's #0 and the previous row's #0, appending to the current row in the format diff, W. If the previous End is false, it simply appends No end defined. Here is my code for this section:

for row in lst:
    row_index = lst.index(row)
    if row_index == 0:
        row.append('x')
    if row[2]==False: # if not start of week
        valBefore = lst[row_index-1][0]
        valCurrent = lst[row_index][0]
        diff = valCurrent-valBefore
        row.append(str(diff)+', D')
    else:
        if lst[row_index-1][3] == True:
            valBefore = lst[row_index-1][0]
            valCurrent = lst[row_index][0]

            diff = valCurrent - valBefore
            row.append(str(diff)+', W')
        else:
            row.append('No end defined')

What I want to be able to do is, if Start is true, but the previous End is False and Holiday is True, it checks the one before that one, and sees if the End is True, and if it is, it will calculate the difference between that row's column #0 and the current row's column #0. If that End is False and Holiday is True, it will go to the row before that and check that, and so on.

I'm stuck on the logic here, and I am unsure of where to go and how to do this, hopefully it makes sense. If someone could point me in the right direction I would really appreciate it!

My expected outcome:

lst=[[1,'a', False, False, False,     ''],
     [3,'b', False, False, False, '2, D'],
     [7,'c', False, True,  False, '4, D'],
     [0,'c', False, False, True,   'Holiday'],
     [13,'d',True,  False, False, '6, W'],
     [21,'e',False, False, False, '8, D'],
     [31,'f',False, False, False, '10, D']]

Upvotes: 2

Views: 176

Answers (1)

yatu
yatu

Reputation: 88276

I'd suggest you to use pandas for such a problem:

import pandas as pd
df = pd.DataFrame(lst, columns=['0','1', 'start', 'end', 'hholiday'])

    0  1  start    end  hholiday
0   1  a  False  False     False
1   3  b  False  False     False
2   7  c  False   True     False
3   0  c  False  False      True
4  13  d   True  False     False
5  21  e  False  False     False
6  31  f  False  False     False

One way to simplify this is using np.where, which allows you to select values according to the result of a condition. The following should do as you want:

import numpy as np
if_true = np.where(df.end.shift().fillna(False), 
                   df['0'] - df['0'].shift(), 
                   'No end defined')
df['diff'] = np.where(df.start, if_true, df['0'] - df['0'].shift())

print(df)

    0  1  start    end  hholiday            diff
0   1  a  False  False     False             nan
1   3  b  False  False     False             2.0
2   7  c  False   True     False             4.0
3   0  c  False  False      True            -7.0
4  13  d   True  False     False  No end defined
5  21  e  False  False     False             8.0
6  31  f  False  False     False            10.0

Upvotes: 3

Related Questions