leo
leo

Reputation: 31

How to numerically sort list of strings containing numbers?

f1 = open("leader")
lines = f1.readlines()
lines.sort(key=int, reverse=True)
f1.close()
print(lines)

with external file values:

345345:player7
435:zo
345:name
23:hello
1231:football

this is to sort them so that the integers are sorted not the names

Upvotes: 2

Views: 108

Answers (3)

GeeTransit
GeeTransit

Reputation: 1468

Try this: (helpful if you are still reading from a file)

with open('leader.txt', mode = 'r') as f1:
    data = f1.readlines()
# end with
keys = {}
output = []
for s in data:
    num, value = s.split(sep=':')
    if keys.get(int(num), False):
        keys[int(num)].append(value)
    else:
        keys[int(num)] = [value]
for num in sorted(keys):
    for i in keys[num]:
        output.append((num, i))
for num, value in output:
    print(f'{num}: {value}')

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140148

The sort key should do: "split once, convert to integer". Not converting to integer fails because then lexicographical compare is used and in that case "10" < "2", not that you want.

l = ['345345:player7',
'435:zo',
'345:name',
'23:hello',
'1231:football']

result = sorted(l, key=lambda x: int(x.split(':',1)[0]))

result:

['23:hello', '345:name', '435:zo', '1231:football', '345345:player7']

that doesn't handle the tiebreaker where numbers are equal. A slightly more complex sort key would be required (but still doable). In that case, drop lambda and create a real function so you can perform split once & unpack to convert only the first part to integer:

def sortfunc(x):
    number,rest = x.split(':',1)
    return int(number),rest

result = sorted(l, key=sortfunc)

Upvotes: 4

Scott Boston
Scott Boston

Reputation: 153460

IIUC:

l = ['345345:player7',
'435:zo',
'345:name',
'23:hello',
'1231:football']

sorted(l, key=lambda x: int(x.split(':')[0]))

Output:

['23:hello', '345:name', '435:zo', '1231:football', '345345:player7']

Upvotes: 4

Related Questions