3

For example i would have a list of of

lists = ['jack 20', 'ben 10', 'alisdar 50', 'ollie 35']

and I would need to sort it so based on the number,

lists.sort() = ['ben 10', 'jack 20', 'ollie 35', 'alisdar 50']

Possible somehow use formatting with split()?

3 Answers 3

13

Use a key function:

lists.sort(key=lambda s: int(s.rsplit(None, 1)[-1]))

The key callable is passed each and every element in lists and that element is sorted according to the return value. In this case we

  • split once on whitespace, starting on the right
  • take the last element of the split
  • turn that into an integer

The argument to key can be any callable, but a lambda is just more compact. You can try it out in the command prompt:

>>> key_function = lambda s: int(s.rsplit(None, 1)[-1])
>>> key_function('ben 10')
10
>>> key_function('Guido van Rossum 42')
42

In effect, when sorting the values are augmented with the return value of that function, and what is sorted is:

[(20, 0, 'jack 20'), (10, 1, 'ben 10'), (50, 2, 'alisdar 50'), (35, 3, 'ollie 35')]

instead (with the second value, the index of the element, added to keep the original order in case of equal sort keys).

Result:

>>> lists = ['jack 20', 'ben 10', 'alisdar 50', 'ollie 35']
>>> lists.sort(key=lambda s: int(s.rsplit(None, 1)[-1]))
>>> lists
['ben 10', 'jack 20', 'ollie 35', 'alisdar 50']
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this great answer, please may you expand on how key = lamdba works? First time i would be using it, Thank you very much.
3

Use a key function that does what you want:

lists.sort(key=lambda e: int(e.split()[1]))

If some of your items don't follow that format, you'll have to write something a little more elaborate.

Comments

1

It would be better if you had a more appropriate data type than a string to represent, say, a person's name and age. One way would be a dictionary:

lists = ['jack 20', 'ben 10', 'alisdar 50', 'ollie 35']
d = dict(item.split(' ') for item in lists)

This constructs a dictionary from a stream of two-element lists.

Then you can sort like this:

print sorted((v, k) for k, v in d.iteritems())

and get this:

>>> lists = ['jack 20', 'ben 10', 'alisdar 50', 'ollie 35']
>>> d = dict(item.split(' ') for item in lists)
>>> print sorted((v, k) for k, v in d.iteritems())
[('10', 'ben'), ('20', 'jack'), ('35', 'ollie'), ('50', 'alisdar')]

Or you could convert age to integer:

>>> lists = ['jack 20', 'ben 10', 'alisdar 50', 'ollie 35']
>>> person_iter = (item.split(' ') for item in lists)
>>> d = {k: int(v) for k, v in person_iter}
>>> print sorted((v, k) for k, v in d.iteritems())
[(10, 'ben'), (20, 'jack'), (35, 'ollie'), (50, 'alisdar')]

person_iter is a generator that produces pairs of name-age. You feed that to the dictionary comprehension and convert the second argument to an integer.

The basic idea, though, is that you will have an easier time if you use more precise data types for your purposes.

3 Comments

So i understand what you did, but for a example how would this be more helpful/ may be easier? Thank you.
You already had several answers, one of which you accepted as your choice. I am not coming at this to solve just your particular problem but to give you a bigger picture of how to approach programming. My solution is comparable in complexity to the others, but when you try to use the data for other problems, you'll find that mine works better because the data structure I am recommending has operations more directly related to what you want to do.
All right i get you, thank you very much for taking the time to comment.

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.