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']]