Reputation: 26151
I'm trying to sort alphanumerics using python. But I can't get them in the order that I would like.
class Lease:
def __init__(self, renter=None, property=None, text=None):
self.renter = renter
self.property = property
self.text = text
lease_list = []
lines = open('input.txt', 'r')
for line in lines:
l, m = line.split(' - ')
l = re.sub(r"\D", "", l)
lease_list.append(Lease(m,l, line))
lines.close()
lease_list.sort(key=lambda obj: obj.property)
for lease in lease_list:
print lease.text
#1B - Jackson
#1A - Brown
#100 - Rice
#50 - Smith
#8 - Smith
#1A - Brown
#1B - Jackson
#8 - Smith
#50 - Smith
#100 - Rice
#50 - Smith
#8 - Smith
#100 - Rice
#1B - Jackson
#1A - Brown
Upvotes: 0
Views: 90
Reputation: 10141
You are removing the literal in here
l = re.sub(r"\D", "", l)
This is what the property list looks like
50
8
100
1
1
So the sorting is correct. The problem is that neither string sorting nor numerical sorting will work. You have to sort first on the number and then on the literal. This will work but it's inefficient. You might need to create a temporary array with the formatted data and sort on it.
for line in lines:
l, m = line.split(' - ')
lease_list.append(Lease(m,l, line))
lease_list.sort(key=lambda obj: (int(re.sub(r"\D", "", obj.property)), re.sub(r"[^A-Z]+", "", obj.property)) )
for lease in lease_list:
print(lease.text)
Just an idea for efficiency:
for line in lines:
l, m = line.split(' - ')
formatted_data.append({'property' : int(re.sub(r"\D", "", l))
, 'literal' : re.sub(r"[^A-Z]", "", l)
, 'm': m
, 'line': line})
formatted_data.sort(key=lambda obj: (obj['property'], obj['literal']))
for lease in formatted_data:
print(lease['line'])
for line in formatted_data:
lease_list.append(Lease(line['m'], line['property'], line['line']))
Upvotes: 3