-2

I want to sort a list of intervals. Each interval is described by a string using symbols '>=' and '<'.

However, there are different patterns of intervals:

  • some intervals have a lower and upper bound, such as '>= 0.45 AND < 0.5';
  • some intervals only have the upper or the lower bound, such as '<0.05';
  • finally, some intervals consists in a single number, such as '1'.

Here is an example list to be sorted:

unique_levels = ['1',
 '>= 0.45 AND < 0.5',
 '>= 0.35 AND < 0.4',
 '>= 0.25 AND < 0.3',
 '>= 0.85 AND < 0.9',
 '>= 0.4 AND < 0.45',
 '>= 0.95 AND < 1',
 '>= 0.55 AND < 0.6',
 '>= 0.3 AND < 0.35',
 '>= 0.2 AND < 0.25',
 '>= 0.15 AND < 0.2',
 '>= 0.5 AND < 0.55',
 '>= 0.6 AND < 0.65',
 '>= 0.9 AND < 0.95',
 '>= 0.8 AND < 0.85',
 '>= 0.75 AND < 0.8',
 '>= 0.05 AND < 0.1',
 '>= 0.65 AND < 0.7',
 '>= 0.7 AND < 0.75',
 '>= 0.1 AND < 0.15',
 '<0.05']

I have tried the following line of code to sort the list:

sorted(unique_levels, key=lambda x: float("".join([i for i in x if i.isdigit()])))

This works for most intervals, but makes a few errors, such as the '1' being at the start of the sorted list, when it should be at the end.

Stef
  • 13,242
  • 2
  • 17
  • 28
43zombiegit
  • 115
  • 1
  • 10
  • 1
    Why did you produce that wrong order in the first place? – Kelly Bundy Aug 20 '21 at 11:40
  • 1
    Can you show us what the expected output should look like? What should be the result after sorting? What is the exact sorting criteria? Just showing a `lambda` function without any explanation makes no sense to me. – ThePyGuy Aug 20 '21 at 11:43
  • @KellyBundy That's essentially the order for the labels on the x-axis on my plot – 43zombiegit Aug 20 '21 at 11:46
  • @ThePyGuy Sure, SO didn't let me as the code was too long. I don't really know what you mean by this - the result should be a sorted list with the places being correct? – 43zombiegit Aug 20 '21 at 11:48
  • 1
    Please take a look at [How to ask](https://stackoverflow.com/help/how-to-ask) And [Minimal Reproducible Example- MRE](https://stackoverflow.com/help/minimal-reproducible-example). Can you add how the above list should look like after it is sorted? – ThePyGuy Aug 20 '21 at 11:51
  • This is after the sort that I mention in the question. From here the 1 needs to be at the end and the 0.95 bound in the right place aswell. ['1', '<0.05', '>= 0.05 AND < 0.1', '>= 0.95 AND < 1', '>= 0.1 AND < 0.15', '>= 0.15 AND < 0.2', '>= 0.2 AND < 0.25', '>= 0.25 AND < 0.3', '>= 0.3 AND < 0.35', '>= 0.35 AND < 0.4', '>= 0.4 AND < 0.45', '>= 0.45 AND < 0.5', '>= 0.5 AND < 0.55', '>= 0.55 AND < 0.6', '>= 0.6 AND < 0.65', '>= 0.65 AND < 0.7', '>= 0.7 AND < 0.75', '>= 0.75 AND < 0.8', '>= 0.8 AND < 0.85', '>= 0.85 AND < 0.9', '>= 0.9 AND < 0.95'] – 43zombiegit Aug 20 '21 at 11:57
  • That doesn't answer my question. So they're x-axis labels. Ok, so what? Why did you produce that wrong order of x-axis labels in the first place? – Kelly Bundy Aug 20 '21 at 12:12
  • Because they're the unique levels in my plots. They don't always sort when plotting – 43zombiegit Aug 20 '21 at 12:14
  • I have a solution inspired by [How to extract a floating number from a string](https://stackoverflow.com/questions/4703390/how-to-extract-a-floating-number-from-a-string) and [Python Sorting How-To: Decorate-Sort-Undecorate](https://docs.python.org/3/howto/sorting.html#the-old-way-using-decorate-sort-undecorate), but since the question has been closed, I can't post it. I don't know why the question was closed. – Stef Aug 21 '21 at 12:19
  • The main idea is: write a function that can correctly map `'>= 0.45 AND < 0.5'` to `[0.45, 0.5]`, `'<0.05'` to `[-math.inf, 0.05]`, and `'1'` to `[1,1]`. Then sort the resulting list of pairs. – Stef Aug 21 '21 at 12:25

1 Answers1

1

If it's just the '1' that's bothering you, you could do:

sorted(unique_levels, key=lambda x: '>=1' if x == '1' else x)

Which returns:

['<0.05', 
'>= 0.05 AND < 0.1', 
'>= 0.1 AND < 0.15', 
'>= 0.15 AND < 0.2', 
'>= 0.2 AND < 0.25', 
'>= 0.25 AND < 0.3', 
'>= 0.3 AND < 0.35', 
'>= 0.35 AND < 0.4', 
'>= 0.4 AND < 0.45', 
'>= 0.45 AND < 0.5', 
'>= 0.5 AND < 0.55', 
'>= 0.55 AND < 0.6', 
'>= 0.6 AND < 0.65', 
'>= 0.65 AND < 0.7', 
'>= 0.7 AND < 0.75', 
'>= 0.75 AND < 0.8', 
'>= 0.8 AND < 0.85', 
'>= 0.85 AND < 0.9', 
'>= 0.9 AND < 0.95', 
'>= 0.95 AND < 1', 
'>=1']
beyarkay
  • 513
  • 3
  • 16
  • It needs to work in any scenario where these kind of strings crop up in lists so for different bounds. – 43zombiegit Aug 20 '21 at 11:56
  • 1
    Can you edit the question to reflect what exactly those scenarios are? Examples are really helpful – beyarkay Aug 20 '21 at 11:58
  • I can't, there's too many. I just need it to work with operators, floats etc – 43zombiegit Aug 20 '21 at 11:58
  • 1
    I want to help but computers don't "just work". If the question you posted doesn't reflect what you want then you need to change the question, add some more examples, clarify what you're wanting to do. – beyarkay Aug 20 '21 at 12:12