1

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')]]
9
  • 3
    why 209 is after 210? And 1076 before 1039 and 1068? Commented Feb 4, 2021 at 8:44
  • 2
    Your original list has 3 levels of nesting, but your result only has 2 levels. Commented Feb 4, 2021 at 8:46
  • This is how the Google API output the response. Commented Feb 4, 2021 at 8:48
  • @buran, he takes the first two marks into consideration. Commented Feb 4, 2021 at 8:49
  • 1
    That still doesn't explain why you want this ordering. Why is [210, 250] before [209, 306] Commented Feb 4, 2021 at 9:28

3 Answers 3

1

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')]]
Sign up to request clarification or add additional context in comments.

17 Comments

@ Barmar this outputs the list in the same ordering as the initial.
All the initial lists are already sorted.
It looks like you also want to sort the list of lists. What's the key for that?
I'm considering the first and second values. In the first row, the first value is 209, the second value is 306.
I don't understand your desired output. Why is [1076, 247, 1228] before [1039, 276, 1091]?
|
0

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

Comments

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.

5 Comments

What will be your output? I get ValueError: invalid literal for int() with base 10: "([210, 250, 345], 'CERTIFICATE')([366, 251, 390], 'OF')"
Thanks. I just corrected the input of my function. (There were nested lists and I got confused).
Could you please copy the whole code and run it? (my_list is the input provided in the question, with three opening brackets: [[[ (....
You can check out the result of combining numbers of another inner list. For instance, feed a new input to the function and print it. For example: print(sort_first_two(my_list[0][2]))
But, again, the solution new_content = [sorted(l, key=lambda x:(x[0][0], x[0][1])) for l in my_list[0]] provided by @Barmar is easier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.