user4581586
user4581586

Reputation:

Why is sort() not working properly?

I am supposed to write a code that initializes an empty list, then read commands and apply them to this list. Everything I have written so far is working great except for sort(), the list was ['5', '10', '9', '1'] and it became ['1', '10', '5', '9'] after sorting which obviously isn't right. That's my code:

N = int(input()) ## number of commands
L = []
for i in range(N):
userInput = input().split()
cmd = userInput[0]
args = userInput[1:]
if cmd == "insert":
    L.insert(int(args[0]), args[1])
elif cmd == "print":
    print(L)
elif cmd == "remove":
    L.remove(args[0])   
elif cmd == "append":
    L.append(args[0])
elif cmd == "sort":
    L.sort() ## the only method that doesn't work properly.
elif cmd == "pop":
    L.pop()
elif cmd == "reverse":
    L.reverse()

Upvotes: 0

Views: 436

Answers (5)

kindall
kindall

Reputation: 184071

If you want the list items to remain strings, the best solution is probably:

L.sort(key=int)

This converts all the strings in the list to integers for comparison purposes, but you don't have to convert them back afterward.

Upvotes: 0

Óscar López
Óscar López

Reputation: 235984

You're doing a string sort on the input list (which is made up of strings representing numbers). Hence a lexicographic sort is performed, and that means that 10 comes after 1 but before 5 (it's the same order words would appear in a dictionary). To get the desired order with the expected data type, try this:

L.sort(key=int)

In the above code we use the integer representation of each element in the list as a key, therefore sorting the list according to the correct order.

Another valid possibility would be to always work with a list of integers (in case you didn't intend the input to be a list of strings). If that makes more sense, modify the following cases to make sure that you handle the right data type:

if cmd == "insert":
    L.insert(int(args[0]), int(args[1]))
elif cmd == "remove":
    L.remove(int(args[0]))
elif cmd == "append":
    L.append(int(args[0]))

Upvotes: 2

Dalen
Dalen

Reputation: 4236

You already know why your sort didn't work as expected.

I just wish to give you better solution than converting everything to integers, then sorting, then back to strings. It is very unefficient.

To do it right, you convert both comparison operands to int and compare them in this form. You do it in the process of sorting and thus avoid 3 loops.

def custom (x, y):
    x = int(x); y = int(y)
    return cmp(x, y)

lst = ['1', '5', '4', '3', '2', '10', '9']
lst.sort(custom)

Upvotes: 0

kardaj
kardaj

Reputation: 1935

In this case, you're applying sort to a list of strings, which means the comparison is based on characters instead of numeric values.

You need to start by mapping your inputs into integers:

args = map(int, args)

Upvotes: 0

Quirk
Quirk

Reputation: 1337

Your list is made up of strings and not integers (or numerals to be precise).

The sort() method is doing a lexicographical sort (as expected on strings). Try casting your input to int.

You could modify the line:

args = userInput[1:]

to:

args = map(int, userInput[1:])

Upvotes: 0

Related Questions