0

I'm trying to sort alphanumerics using python. But I can't get them in the order that I would like.

printer.py

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

current output

#1B - Jackson
#1A - Brown
#100 - Rice
#50 - Smith
#8 - Smith

desired output

#1A - Brown
#1B - Jackson
#8 - Smith
#50 - Smith
#100 - Rice

input.txt

#50 - Smith
#8 - Smith
#100 - Rice
#1B - Jackson
#1A - Brown
9
  • 1
    what does the input look like? you sort over property but you are printing only text. Commented Jan 21, 2016 at 17:04
  • I dont understand how you are sorting to get your desired output... (Ie why is K before A if you are sorting on names ... or why is 1B before 8 if you are sorting on the numbers) Commented Jan 21, 2016 at 17:04
  • Please describe the ordering your want. Commented Jan 21, 2016 at 17:05
  • 1
    Is your python script really in a file called "printer.rb" ? Commented Jan 21, 2016 at 17:05
  • maybe this is supposed to be a ruby script? Commented Jan 21, 2016 at 17:06

1 Answer 1

3

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']))
Sign up to request clarification or add additional context in comments.

1 Comment

@dabhand That give me "100, 1A, 1B, 50, 8"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.