Home > Blockchain >  How to group and order list of lists based on certain flags in the list?
How to group and order list of lists based on certain flags in the list?

Time:04-11

I was working on an automation problem where I end up with a list of lists which look something like this:

in_list=[ ['data_1_1', 'id_1', True, False, False, False, 'data_1_5'],
          ['data_2_1', 'id_1', False, True, False, False, 'data_2_5'],
          ['data_3_1', 'id_2', True, False, False, False, 'data_3_5'],
          ['data_4_1', 'id_1', True, False, False, False, 'data_4_5'],
          ['data_5_1', 'id_1', False, True, False, False, 'data_5_5'],
          ['data_6_1', 'id_2', True, False, False, False, 'data_6_5'] ]

I wanted to group the lists based on the id(2nd element in each list) and order it based on the flags (3rd, 4th, 5th, 6th element of the list),

Expected output:

out_list=[ ['data_1_1', 'id_1', True, False, False, False, 'data_1_5'],
           ['data_4_1', 'id_1', True, False, False, False, 'data_4_5'],
           ['data_2_1', 'id_1', False, True, False, False, 'data_2_5'],
           ['data_5_1', 'id_1', False, True, False, False, 'data_5_5'],
           ['data_3_1', 'id_2', True, False, False, False, 'data_3_5'],
           ['data_6_1', 'id_2', True, False, False, False, 'data_6_5'] ]

Explanation: out_list is grouped in the same order w.r.t id and further ordered based on the True/False flags, (simply put, the lists which have the same set of flags and the same id come together)

So far, I am iterating over the entire list of lists and checking element by element which is neither pythonic nor scalable. Is there a faster/better way to do it?

CodePudding user response:

Your expected output isn't grouping anything, just sorting the elements in the outer list.

Since you want to order by the ID and then by the flags, use a slice of the inner list that contains these elements as your sort key

in_list=[ ['data_1_1', 'id_1', True, False, False, False, 'data_1_5'],
          ['data_2_1', 'id_1', False, True, False, False, 'data_2_5'],
          ['data_3_1', 'id_2', True, False, False, False, 'data_3_5'],
          ['data_4_1', 'id_1', True, False, False, False, 'data_4_5'],
          ['data_5_1', 'id_1', False, True, False, False, 'data_5_5'],
          ['data_6_1', 'id_2', True, False, False, False, 'data_6_5'] ]

sorted(in_list, key=lambda x: x[1:6])

Which gives this:

[['data_2_1', 'id_1', False, True, False, False, 'data_2_5'],
 ['data_5_1', 'id_1', False, True, False, False, 'data_5_5'],
 ['data_1_1', 'id_1', True, False, False, False, 'data_1_5'],
 ['data_4_1', 'id_1', True, False, False, False, 'data_4_5'],
 ['data_3_1', 'id_2', True, False, False, False, 'data_3_5'],
 ['data_6_1', 'id_2', True, False, False, False, 'data_6_5']]

If you want to sort the True flags first, you'll have to negate them in the key function.

>>> sorted(in_list, key=lambda x: [x[1]]   [not f for f in x[2:6]])

[['data_1_1', 'id_1', True, False, False, False, 'data_1_5'],
 ['data_4_1', 'id_1', True, False, False, False, 'data_4_5'],
 ['data_2_1', 'id_1', False, True, False, False, 'data_2_5'],
 ['data_5_1', 'id_1', False, True, False, False, 'data_5_5'],
 ['data_3_1', 'id_2', True, False, False, False, 'data_3_5'],
 ['data_6_1', 'id_2', True, False, False, False, 'data_6_5']]
  • Related