2

I have a list like this

data = [('£3.46', 'I001'), ('£10.46', 'I002')] 

I want to sort this list with

data.sort()

however the sorted list puts £10.46 before £3.46, I'm assuming this is because the data is a string and £1 comes before £3.
I have tried looking at lambda functions but I can't get my head around it.

1
  • 1
    You don't have to use a lambda. You can write a regular function that returns the value you want to sort with and use that function for the key argument. docs.python.org/3/howto/sorting.html Commented Apr 24, 2022 at 21:58

3 Answers 3

2

One option is to strip "£" and convert the number to float as a sorting key:

data.sort(key=lambda x: float(x[0].lstrip('£')))
print(data)

Output:

[('£3.46', 'I001'), ('£10.46', 'I002')]
Sign up to request clarification or add additional context in comments.

2 Comments

Strip pound symbol and cast to float type using float(). Or even better, do not include pound symbols and strings to represent a numeric value at all! Only add pound symbol and convert it to string when you need to output the result.
This is perfect, just what I needed. So to break down the code, key tells the sort function that instead of using the value to instead use the result from the lambda function float(x[0].lstrip('£'))?
1

You could achieve that in this simple way:

data = [('£10.46', 'I002'), ('£3.46', 'I001')]
def sort_tuple(item):
    return float(item[0][1:])

print(sorted(data, key=sort_tuple))

Output:

[('£3.46', 'I001'), ('£10.46', 'I002')]

Process finished with exit code 0

1 Comment

This is also a great answer thank you. Combining this with enke's solution I changed the return line to "return float(item[0].lstrip('£'))"
0

This is a general approach with some limitations, but should work in a wide variety of similar situations.

import re

def float_then_text(values):
    '''Convert [str, str, ...] to [(float, str), (float, str), ...]'''
    return [(float(re.sub(r'[^\d.]+', '', text)), text) for
for text in values]

data = [('£3.46', 'I001'), ('£10.46', 'I002')]

data.sort(key=float_then_text)

The function float_then_text will convert from ('£3.46', 'I001') to [(3.46, '£3.46'), (1.0, 'I001')] and so on.

Including the text in the keys is optional, but ensures that values with different units get their units sorted in the same order each time as well.

4 Comments

You're better off just letting that ValueError propagate... where a mix of text/None/float escape - the sort's going to fail anyway
and that's not how you should be passing it as a key function anyway... the function should return the value to be considered for the sorting... and called as data.sort(key=float_then_text).
@JonClements sort(key=...) can't sort on a generator, so you have to convert to a sortable quantity like a list first. (Notice that float_then_text is a generator using yield.) Your first point is quite an issue with my answer, and I'm refactoring the answer now to address it)
Yeah... so you don't make float_then_text a generator... make it a function that takes a single value and returns a single value...

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.