Python Forum
sorting 2D lists by column
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sorting 2D lists by column
#1
Hello everyone,

I would like to sort a multidimensional list by the second column.

Example:
x = [
    [1,18,2],
    [2,9,4],
    [3,1,1]
    ]

x = sorted(x, key=lambda x: x[2])
print(x)
The output I am looking for should be:
[
[3,1,1],
[2,9,4],
[1,18,2]
]
Unfortunately lamdba sorts like this:
[
[3,1,1],
[1,18,2],
[2,9,4]
]
So lamda does put 18 below 9, because of the '1' in the front.
I did try numpy arrays too, but I just can't find the right way.
Can anyone help me with this problem?

thank you very much!
/ToffieFaye
Reply
#2
You are not sorting by second column. As Python uses 0-based indexing you are sorting by third column.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
Well, that is embarrasing.
Thank you! If I change 2 to 1 it works in the simple example.

Originally I wanted to sort a list out of a file and there it still doesn't work.
I'll show you the whole code. Maybe you can help?
I'd honestly really appreciate that!

So this is the code:

with open('example.txt','r') as textFile2:
    data_list = [line.split() for line in textFile2]
textFile2.close()

data_list = sorted(data_list, key=lambda data_list: data_list[1])

print(data_list)
and this is how the example.txt file looks like:
16	43	23.5	85.8
17	61	21.1	86.4
18	40	22.5	90.0
19	37	28.5	86.1
20	22	19.4	78.9
21	156	29.2	89.2
22	63	35.4	86.3
23	105	31.3	86.7
This is the output:
Output:
[['23', '105', '31.3', '86.7'], ['21', '156', '29.2', '89.2'], ['20', '22', '19.4', '78.9'], ['19', '37', '28.5', '86.1'], ['18', '40', '22.5', '90.0'], ['16', '43', '23.5', '85.8'], ['17', '61', '21.1', '86.4'], ['22', '63', '35.4', '86.3']]
It works for the numbers with 2 letters, but it still puts 105 and 156 in the front and I don't know why.
Do you understand that?
Reply
#4
what you show are strings, not numbers. you need to convert them to number (e.g. float) in order to compare them as you expect
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
Some observations:

- you don't need to close file if using 'with' (Python does it for you)
- as buran pointed out you sorting strings not ints

Just convert into int and you are good to go: int(data_list[1])
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#6
(Sep-25-2019, 06:42 AM)buran Wrote: what you show are strings, not numbers. you need to convert them to number (e.g. float) in order to compare them as you expect
I already tried that.. doesn't make a difference..
I put
map(float, data_list)
as a line before the sorting command

(Sep-25-2019, 06:55 AM)perfringo Wrote: Some observations: - you don't need to close file if using 'with' (Python does it for you) - as buran pointed out you sorting strings not ints Just convert into int and you are good to go: int(data_list[1])
(Sep-25-2019, 06:55 AM)perfringo Wrote: Some observations: - you don't need to close file if using 'with' (Python does it for you) - as buran pointed out you sorting strings not ints Just convert into int and you are good to go: int(data_list[1])
thank you! It still doesn't work though..
Output:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
Reply
#7
If you need all data to be floats then you can do it while reading the file. Just add conversion into list comprehension (row #2):

[[float(x) for x in line.split()] for line in textFile2]

(Sep-25-2019, 06:55 AM)ToffieFaye Wrote: It still doesn't work though..

based on 'data' you provided:

>>> sorted(data, key=lambda x: int(x[1]))                 
[['20', '22', '19.4', '78.9'],
 ['19', '37', '28.5', '86.1'],
 ['18', '40', '22.5', '90.0'],
 ['16', '43', '23.5', '85.8'],
 ['17', '61', '21.1', '86.4'],
 ['22', '63', '35.4', '86.3'],
 ['23', '105', '31.3', '86.7'],
 ['21', '156', '29.2', '89.2']]
No errors and sorted by second column.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#8
although I prefer list comprehension as shown by @perfringo, if you prefer map
data_list = [list(map(float, line.split())) for line in textFile2]
ToffieFaye likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
(Sep-25-2019, 07:23 AM)buran Wrote: although I prefer list comprehension as shown by @perfringo, if you prefer map
data_list = [list(map(float, line.split())) for line in textFile2]
thank you so much @perfringo and @buran!!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020