0

I would like to sort a 2D list, but by using the last column as the sorter. Here is the list:

list_2 = [['countries', 2019, 2020, 2025],['aruba', 2,2,9],['barbados', 2,2,3],['japan', 2,2,5]]

The first row with countries and years, must not be sorted. The second third and fourth row with countries and data needs be sorted by the last column. Here is my function so far:

#create a new analyzed and sorted list, empty, to be used in further analysis
listAnalyzedSort = []

def sortData(lista):
    #this function sorts data in the inputed list
    #inputed argument is a list
    #output is a sorted list by the last column
    while lista:
        minimum = lista[1][3]   
        for row in lista:
            for column in row[1:]:
                if column[3] < minimum:
                    minimum = column
                    listAnalyzedSort.append(minimum)
                    lista.remove(minimum)
        return listAnalyzedSort

sortData(list_2)

It gives me an error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Users\JONATH~1.COL\AppData\Local\Temp/ipykernel_10168/956311210.py in <module>
     18         return listAnalyzedSort
     19 
---> 20 sortData(list_2)

C:\Users\JONATH~1.COL\AppData\Local\Temp/ipykernel_10168/956311210.py in sortData(lista)
     12         for row in lista:
     13             for column in row[1:]:
---> 14                 if column[3] < minimum:
     15                     minimum = column
     16                     listAnalyzedSort.append(minimum)

TypeError: 'int' object is not subscriptable
``
4
  • Judging from the error, your code is trying to iterate over a single integer. I suppose you went a level too deep at some point. Commented Mar 17, 2022 at 9:12
  • You need to include the entire traceback in your question — not just the last line of it. Commented Mar 17, 2022 at 9:12
  • if column[3] < minimum: column here is already a row item so it wont be always subscriptable. you always want to look at the 4th item then you dont need the loop for column in row[1:]: just the if. if all you want to do is sort then why not provide a custom key? also, its a big no no modifying your list while iterating over it lista.remove(minimum) is bad! Commented Mar 17, 2022 at 9:12
  • but Nullman if I do that then 'column' becomes a variable which is not defined. Commented Mar 17, 2022 at 9:26

3 Answers 3

1

Just exclude the first entry and then sort the remaining, later just append the first country to the result

lista = [['countries', 2019, 2020, 2025],['aruba', 2,2,1],['barbados', 2,2,2],['japan', 2,2,3]]
sortedout = sorted(lista[1:],key=lambda x:x[-1], reverse=True)
out = [lista[0]]+sortedout
print(out)

output will be

[['countries', 2019, 2020, 2025], ['japan', 2, 2, 3], ['barbados', 2, 2, 2], ['aruba', 2, 2, 1]]
Sign up to request clarification or add additional context in comments.

3 Comments

I updated the code. Allow me to add more explanations. This is for a course, so I cannot use sort() nor sorted(). What I am looking for as a returned list, is the first row unchanged (countries, years), but the next three rows in a new order. For the moment they are in Aruba, Barbados, Japan, but I will now change the data in list_2, so that the returned list should have the countries(and all of their data in their row of course) in a new order. That is what I need the function to do :)
Now the order after the function should be barbardos, , japan, aruba
Then @fabioklr approach is what you are looking for. The code you have posted has many issues as below. 1. never removing the first row, which will result in infinite loop 2. for column in row[1:] takes second elem is each row, you cannot do column[3] later 3. you cannot remove minimum from lista. minimum is just a number, its not an element of lista 4. you are considering lista[1][3] as minimum, which is wrong assumption. your output will not be sorted if lista[1][3] is not minimum
0

Only sort the list starting at the element at index 1 and use a key function that retrieves the last element of the inner list. Then add this new sorted list to the element at index 0.

lista = [['countries', 2019, 2020, 2025],['japan', 2,2,3],['barbados', 2,2,2],['aruba', 2,2,1]]
result = lista[0] + sorted(lista[1:], key=lambda x: x[-1])
print(result)

This will give you ['countries', 2019, 2020, 2025, ['aruba', 2, 2, 1], ['barbados', 2, 2, 2], ['japan', 2, 2, 3]]

1 Comment

thanks matthias but i cant use any sort or sorted functions, have to write my own
0

Here you will find a solution that is similar to your approach.

def sortData(lista):
    listAnalyzedSort = lista[:2]
    del lista[:2]
    for row in lista:
        max = 1
        for idx, ele in enumerate(listAnalyzedSort[1:]):
            if row[3] < ele[3]:
                max = idx + 1
        listAnalyzedSort.insert(max, row)
    
    return listAnalyzedSort

Note that it tries to follow your logic by comparing the third element of a given row to the third element of every row of the resulting list, and then inserting the given row at the appropriate position.

It returns: [['countries', 2019, 2020, 2025], ['barbados', 2, 2, 3], ['japan', 2, 2, 5], ['aruba', 2, 2, 9]]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.