I have a pandas column of lists of consecutive log actions that users do, while posting a photo in mobile app in each whole logging session. Suppose the single list looks like:
my_list = [
      'action_a', 'action_b', 'action_c', 'action_z', 
      'action_j',
      'action_a','action_b', 
      'action_a', 'action_b', 'action_z']
1) action_a - the start of photo upload
2) action_z - the end of photo upload
3) other actions_i - all the actions that can occur between action_a and action_z.
4) there may be errors, like 'action_j', that appear not between 'action_a', 'action_z' and we shouldn't take them into account
5) the process of photo upload may not be completed - so there may be path like 'action_a','action_b'.
The GOAL = separate my_list into sublists of all action paths that starts with 'action_a' and ends with 'action_z' or ends before another 'action_a'. So the result should be like that:
['action_a', 'action_b', 'action_c', 'action_z'] 
['action_a','action_b']
['action_a', 'action_b', 'action_z']
So currently I am trying to solve it like that: firstly I've deleted all my_lists, where the number of 'action_z' is greater than the number of 'action_a' or where there is no 'action_a'. Then I did that:
indices_a = [i for i, x in enumerate(my_list) if x == "action_a"]
indices_z = [i for i, x in enumerate(my_list) if x == "action_z"]
if(len(indices_z)<1):
    for i_a,x_a in enumerate(indices_a):
        if (i_a+1 != len(indices_a)):
            indices_z.append(indices_a[i_a+1]-1) 
        else: indices_z.append(len(my_list)-1) 
else:       
    for i_a,x_a in enumerate(indices_a):
        if (i_a+1 != len(indices_a)):
            if (indices_z[i_a] > indices_a[i_a+1] ):
                indices_z.insert(i_a, indices_a[i_a+1]-1)
        else:  indices_z.append(len(my_list)-1) 
res=[]
for i,j in zip(indices_a, indices_z):
    res.append(my_list[i:j+1] )
Seems like it works. What is the better way?
I've tried to simplify things a little and came up with this logic:
result = []
curr_list = None
for item in my_list:
    if item == 'action_a':
        if curr_list is not None:
            # Only append is there is content
            result.append(curr_list)
        # Create a new list
        curr_list = []
    try:
        # Try to append the current item
        curr_list.append(item)
        if item == 'action_z':
            # Close the current list but don't initialize 
            # a new one until we encounter action_a
            result.append(curr_list)
            curr_list = None
    except AttributeError:
        # This means we haven't encountered action_a yet
        # Just ignore and move on
        pass
if curr_list is not None:
    # Append an "open" list if there is one
    result.append(curr_list)
for item in result:
    print(item)
Result:
['action_a', 'action_b', 'action_c', 'action_z']
['action_a', 'action_b']
['action_a', 'action_b', 'action_z']
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With