简体   繁体   中英

Sort a list of list using two values from each list

How can I sort this list of list using the first and second number in each list [210, 250, 345] . I want to consider the first values first.

my_list  =   [[[([210, 250, 345], 'CERTIFICATE'), ([366, 251, 390], 'OF'), ([397, 252, 551], 'REGISTRATION')], 
               [([1076, 247, 1228], 'SERTIFIKAAT'), ([1234, 248, 1283], 'VAN'), ([1285, 248, 1422], 'REGISTRASIE')],
               [([210, 278, 236], 'IN'), ([237, 277, 330], 'RESPECT'), ([351, 277, 376], 'OF'), ([375, 277, 455], 'MOTOR'),([463, 275, 551], 'VEHICLE')], 
               [([1039, 276, 1091], 'TEN'), ([1093, 276, 1190], 'OPSIGTE'),([1195, 276, 1246], 'VAN'), ([1257, 276, 1448], 'MOTORVOERTUIG')], 
               [([209, 306, 297], '(National'), ([306, 306, 355], 'Road'), ([368, 308, 430], 'Traffic'), ([437, 305, 480], 'Act,'), ([491, 304, 554], '1996)')], 
               [([770, 293, 787], 'IKE'), ([788, 306, 796], 'E')], 
               [([1068, 303, 1174], '(Nasionale'), ([1181, 304, 1372], 'Padverkeerswet,'), ([1374, 304, 1424], '1996)')]]
              ]

I've tried:

new_content = []

for i,j in enumerate(my_list):
    chunk = sorted(my_list[i], key=lambda x:(x[0][0], x[0][1]))
    new_content.append(chunk)
    

And:

for i,j in enumerate(my_list):
    chunk = sorted(my_list, key=lambda x:(x[i][0][0], x[i][0][1]))
    new_content.append(chunk)

And:

for i,j in enumerate(my_list):
    chunk = sorted(my_list, key=lambda x:(x[i][0][0], x[i+1][0][1]))
    new_content.append(chunk)

Desire result:

new_list = [[([210, 250, 345], 'CERTIFICATE'), ([366, 251, 390], 'OF'), ([397, 252, 551], 'REGISTRATION')],
            [([210, 278, 236], 'IN'), ([237, 277, 330], 'RESPECT'), ([351, 277, 376], 'OF'), ([375, 277, 455], 'MOTOR'), ([463, 275, 551], 'VEHICLE')],
            [([209, 306, 297], '(National'), ([306, 306, 355], 'Road'), ([368, 308, 430], 'Traffic'), ([437, 305, 480], 'Act,'), ([491, 304, 554], '1996)')],
            [([770, 293, 787], 'IKE'), ([788, 306, 796], 'E')],
            [([1076, 247, 1228], 'SERTIFIKAAT'), ([1234, 248, 1283], 'VAN'), ([1285, 248, 1422], 'REGISTRASIE')]
            [([1039, 276, 1091], 'TEN'), ([1093, 276, 1190], 'OPSIGTE'), ([1195, 276, 1246], 'VAN'), ([1257, 276, 1448], 'MOTORVOERTUIG')],
            [([1068, 303, 1174], '(Nasionale'), ([1181, 304, 1372], 'Padverkeerswet,'), ([1374, 304, 1424], '1996)')],
            [([1076, 247, 1228], 'SERTIFIKAAT'), ([1234, 248, 1283], 'VAN'), ([1285, 248, 1422], 'REGISTRASIE')]]

Your first attempt was close, but you didn't notice that there's an extra level of list wrapped around everything. So you need to loop over my_list[0] .

There's also no need to use enumerate() . You don't need the indexes, just the list elements. And you can use a list comprehension to collect the results into a list.

new_content = [sorted(l, key=lambda x:(x[0][0], x[0][1])) for l in my_list[0]]
new_content.sort(key = lambda x: (x[0][0][0], x[0][0][1]))

Result:

new_list = [[([209, 306, 297], '(National'), ([306, 306, 355], 'Road'), ([368, 308, 430], 'Traffic'), ([437, 305, 480], 'Act,'), ([491, 304, 554], '1996)')],
            [([210, 250, 345], 'CERTIFICATE'), ([366, 251, 390], 'OF'), ([397, 252, 551], 'REGISTRATION')],
            [([210, 278, 236], 'IN'), ([237, 277, 330], 'RESPECT'), ([351, 277, 376], 'OF'), ([375, 277, 455], 'MOTOR'), ([463, 275, 551], 'VEHICLE')],
            [([770, 293, 787], 'IKE'), ([788, 306, 796], 'E')],
            [([1039, 276, 1091], 'TEN'), ([1093, 276, 1190], 'OPSIGTE'), ([1195, 276, 1246], 'VAN'), ([1257, 276, 1448], 'MOTORVOERTUIG')],
            [([1068, 303, 1174], '(Nasionale'), ([1181, 304, 1372], 'Padverkeerswet,'), ([1374, 304, 1424], '1996)')],
            [([1076, 247, 1228], 'SERTIFIKAAT'), ([1234, 248, 1283], 'VAN'), ([1285, 248, 1422], 'REGISTRASIE')]]

First of all we extract the list, since the first nesting level is unused here

my_list = my_list[0]

Then we could sort each element (each element is a list of tuple), by getting:

  1. The first element that is a tuple(list, str)
  2. The first element of the tuple that is a list
  3. The fist element of the nested list (at 2.)

sorted(my_list, key = lambda x: x[0][0][0])

I think whether @Bruno would like to sort all the included lists together, or just each included list individually (which I think this is what he is looking for according to its desire result since the nested lists are sorted individually not all togehter), the concept and approach provided by @barmar is the same (just by doing some minor changes you can get what you are looking for)

==============================

I didn't know about sorted(), so I come up with this approach (which is not as easy as the sorted() solution) You can convert the first and second numbers (in each tuple) to string. Then, make sure the first numbers have the same length (if not, extend them by adding 0 before them). Do the same thing for second numbers. Then, join the numbers (that are in string format) together and convert it back to integer. Now, you have only one number based on which you can do sorting!

def sort_first_two(my_list = my_list[0][0]):
    first_val = []
    second_val = []

    for item in my_list:
        first_val.append(str(item[0][0]))
        second_val.append((str(item[0][1])))

    max_len_first = max([len(val) for val in first_val])
    max_len_second = max([len(val) for val in second_val])

    first_val_extended = [('0'*(max_len_first-len(val))+val) for val in first_val]
    second_val_extended = [('0'*(max_len_second-len(val))+val) for val in second_val]


    combined_val = [int(a+b) for a,b in zip(first_val_extended,second_val_extended)]

    return combined_val


print(sort_first_two(my_list[0][0]))

This gives you the combination of first and second numbers, and then you can just sort them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM