Python if-else code style for reduced code for rounding floats2019 Community Moderator ElectionIs floating...

Hacking a Safe Lock after 3 tries

Most cost effective thermostat setting: consistent temperature vs. lowest temperature possible

Is a party consisting of only a bard, a cleric, and a warlock functional long-term?

How to make healing in an exploration game interesting

What approach do we need to follow for projects without a test environment?

Is there a data structure that only stores hash codes and not the actual objects?

Should we release the security issues we found in our product as CVE or we can just update those on weekly release notes?

What should tie a collection of short-stories together?

Can a druid choose the size of its wild shape beast?

Audio processing. Is it possible to directly access the decoded audio data going into the analog input of a computer

SOQL: Populate a Literal List in WHERE IN Clause

Define, (actually define) the "stability" and "energy" of a compound

Is it possible to upcast ritual spells?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

What is the rarity of this homebrew magic staff?

Declaring defaulted assignment operator as constexpr: which compiler is right?

Sailing the cryptic seas

Property of summation

If I can solve Sudoku can I solve Travelling Salesman Problem(TSP)? If yes, how?

Are there verbs that are neither telic, or atelic?

Did Ender ever learn that he killed Stilson and/or Bonzo?

How to write cleanly even if my character uses expletive language?

How to change two letters closest to a string and one letter immediately after a string using notepad++

how to write formula in word in latex



Python if-else code style for reduced code for rounding floats



2019 Community Moderator ElectionIs floating point math broken?How do I parse a string to a float or int in Python?Printing increments of 0.1 in c#How can I force division to be floating point? Division keeps rounding down to 0?Double increments in JavaPut integers from stdin in listSelecting lines of a file specified by a list of stringsPerfect ROC curve but imperfect prediction accuracyFor loop break doesn't work PythonHow to classify observations based on their covariates in dataframe and numpy?Parse dataframe with specific column and write to sheets in one excel file












15















Is there any shorter, more legible code style to solve this problem?
I am trying to classify some float values into interregional folders.



def classify(value):   
if value < -0.85 and value >= -0.95:
ts_folder = r'-0.9'
elif value < -0.75 and value >= -0.85:
ts_folder = r'-0.8'
elif value < -0.65 and value >= -0.75:
ts_folder = r'-0.7'
elif value < -0.55 and value >= -0.65:
ts_folder = r'-0.6'
elif value < -0.45 and value >= -0.55:
ts_folder = r'-0.5'
elif value < -0.35 and value >= -0.45:
ts_folder = r'-0.4'
elif value < -0.25 and value >= -0.35:
ts_folder = r'-0.3'
elif value < -0.15 and value >= -0.25:
ts_folder = r'-0.2'
elif value < -0.05 and value >= -0.15:
ts_folder = r'-0.1'
elif value < 0.05 and value >= -0.05:
ts_folder = r'.0'
elif value < 0.15 and value >= 0.05:
ts_folder = r'.1'
elif value < 0.25 and value >= 0.15:
ts_folder = r'.2'
elif value < 0.35 and value >= 0.25:
ts_folder = r'.3'
elif value < 0.45 and value >= 0.35:
ts_folder = r'.4'
elif value < 0.55 and value >= 0.45:
ts_folder = r'.5'
elif value < 0.65 and value >= 0.55:
ts_folder = r'.6'
elif value < 0.75 and value >= 0.65:
ts_folder = r'.7'
elif value < 0.85 and value >= 0.75:
ts_folder = r'.8'
elif value < 0.95 and value >= 0.85:
ts_folder = r'.9'

return ts_folder









share|improve this question




















  • 46





    That is the longest code for a rounding function I've ever seen!

    – Aran-Fey
    13 hours ago











  • I agree with @Aran-Fey. That thing's huge, OP!

    – connectyourcharger
    13 hours ago











  • That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

    – Kuang 鄺世銘
    12 hours ago






  • 6





    At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

    – chepner
    11 hours ago






  • 3





    It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

    – Eric Duminil
    6 hours ago
















15















Is there any shorter, more legible code style to solve this problem?
I am trying to classify some float values into interregional folders.



def classify(value):   
if value < -0.85 and value >= -0.95:
ts_folder = r'-0.9'
elif value < -0.75 and value >= -0.85:
ts_folder = r'-0.8'
elif value < -0.65 and value >= -0.75:
ts_folder = r'-0.7'
elif value < -0.55 and value >= -0.65:
ts_folder = r'-0.6'
elif value < -0.45 and value >= -0.55:
ts_folder = r'-0.5'
elif value < -0.35 and value >= -0.45:
ts_folder = r'-0.4'
elif value < -0.25 and value >= -0.35:
ts_folder = r'-0.3'
elif value < -0.15 and value >= -0.25:
ts_folder = r'-0.2'
elif value < -0.05 and value >= -0.15:
ts_folder = r'-0.1'
elif value < 0.05 and value >= -0.05:
ts_folder = r'.0'
elif value < 0.15 and value >= 0.05:
ts_folder = r'.1'
elif value < 0.25 and value >= 0.15:
ts_folder = r'.2'
elif value < 0.35 and value >= 0.25:
ts_folder = r'.3'
elif value < 0.45 and value >= 0.35:
ts_folder = r'.4'
elif value < 0.55 and value >= 0.45:
ts_folder = r'.5'
elif value < 0.65 and value >= 0.55:
ts_folder = r'.6'
elif value < 0.75 and value >= 0.65:
ts_folder = r'.7'
elif value < 0.85 and value >= 0.75:
ts_folder = r'.8'
elif value < 0.95 and value >= 0.85:
ts_folder = r'.9'

return ts_folder









share|improve this question




















  • 46





    That is the longest code for a rounding function I've ever seen!

    – Aran-Fey
    13 hours ago











  • I agree with @Aran-Fey. That thing's huge, OP!

    – connectyourcharger
    13 hours ago











  • That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

    – Kuang 鄺世銘
    12 hours ago






  • 6





    At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

    – chepner
    11 hours ago






  • 3





    It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

    – Eric Duminil
    6 hours ago














15












15








15


3






Is there any shorter, more legible code style to solve this problem?
I am trying to classify some float values into interregional folders.



def classify(value):   
if value < -0.85 and value >= -0.95:
ts_folder = r'-0.9'
elif value < -0.75 and value >= -0.85:
ts_folder = r'-0.8'
elif value < -0.65 and value >= -0.75:
ts_folder = r'-0.7'
elif value < -0.55 and value >= -0.65:
ts_folder = r'-0.6'
elif value < -0.45 and value >= -0.55:
ts_folder = r'-0.5'
elif value < -0.35 and value >= -0.45:
ts_folder = r'-0.4'
elif value < -0.25 and value >= -0.35:
ts_folder = r'-0.3'
elif value < -0.15 and value >= -0.25:
ts_folder = r'-0.2'
elif value < -0.05 and value >= -0.15:
ts_folder = r'-0.1'
elif value < 0.05 and value >= -0.05:
ts_folder = r'.0'
elif value < 0.15 and value >= 0.05:
ts_folder = r'.1'
elif value < 0.25 and value >= 0.15:
ts_folder = r'.2'
elif value < 0.35 and value >= 0.25:
ts_folder = r'.3'
elif value < 0.45 and value >= 0.35:
ts_folder = r'.4'
elif value < 0.55 and value >= 0.45:
ts_folder = r'.5'
elif value < 0.65 and value >= 0.55:
ts_folder = r'.6'
elif value < 0.75 and value >= 0.65:
ts_folder = r'.7'
elif value < 0.85 and value >= 0.75:
ts_folder = r'.8'
elif value < 0.95 and value >= 0.85:
ts_folder = r'.9'

return ts_folder









share|improve this question
















Is there any shorter, more legible code style to solve this problem?
I am trying to classify some float values into interregional folders.



def classify(value):   
if value < -0.85 and value >= -0.95:
ts_folder = r'-0.9'
elif value < -0.75 and value >= -0.85:
ts_folder = r'-0.8'
elif value < -0.65 and value >= -0.75:
ts_folder = r'-0.7'
elif value < -0.55 and value >= -0.65:
ts_folder = r'-0.6'
elif value < -0.45 and value >= -0.55:
ts_folder = r'-0.5'
elif value < -0.35 and value >= -0.45:
ts_folder = r'-0.4'
elif value < -0.25 and value >= -0.35:
ts_folder = r'-0.3'
elif value < -0.15 and value >= -0.25:
ts_folder = r'-0.2'
elif value < -0.05 and value >= -0.15:
ts_folder = r'-0.1'
elif value < 0.05 and value >= -0.05:
ts_folder = r'.0'
elif value < 0.15 and value >= 0.05:
ts_folder = r'.1'
elif value < 0.25 and value >= 0.15:
ts_folder = r'.2'
elif value < 0.35 and value >= 0.25:
ts_folder = r'.3'
elif value < 0.45 and value >= 0.35:
ts_folder = r'.4'
elif value < 0.55 and value >= 0.45:
ts_folder = r'.5'
elif value < 0.65 and value >= 0.55:
ts_folder = r'.6'
elif value < 0.75 and value >= 0.65:
ts_folder = r'.7'
elif value < 0.85 and value >= 0.75:
ts_folder = r'.8'
elif value < 0.95 and value >= 0.85:
ts_folder = r'.9'

return ts_folder






python floating-point rounding number-formatting






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 48 mins ago









smci

15.3k677108




15.3k677108










asked 13 hours ago









Kuang 鄺世銘Kuang 鄺世銘

826




826








  • 46





    That is the longest code for a rounding function I've ever seen!

    – Aran-Fey
    13 hours ago











  • I agree with @Aran-Fey. That thing's huge, OP!

    – connectyourcharger
    13 hours ago











  • That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

    – Kuang 鄺世銘
    12 hours ago






  • 6





    At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

    – chepner
    11 hours ago






  • 3





    It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

    – Eric Duminil
    6 hours ago














  • 46





    That is the longest code for a rounding function I've ever seen!

    – Aran-Fey
    13 hours ago











  • I agree with @Aran-Fey. That thing's huge, OP!

    – connectyourcharger
    13 hours ago











  • That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

    – Kuang 鄺世銘
    12 hours ago






  • 6





    At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

    – chepner
    11 hours ago






  • 3





    It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

    – Eric Duminil
    6 hours ago








46




46





That is the longest code for a rounding function I've ever seen!

– Aran-Fey
13 hours ago





That is the longest code for a rounding function I've ever seen!

– Aran-Fey
13 hours ago













I agree with @Aran-Fey. That thing's huge, OP!

– connectyourcharger
13 hours ago





I agree with @Aran-Fey. That thing's huge, OP!

– connectyourcharger
13 hours ago













That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

– Kuang 鄺世銘
12 hours ago





That's an example. In my experiment, diffence isn't always 0.5. round() is a good way in this case but not always work for me

– Kuang 鄺世銘
12 hours ago




6




6





At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

– chepner
11 hours ago





At the very least, use chained comparisons: -0.95 <= value < -0.85 instead of `value < -0.85 and value >= -0.95

– chepner
11 hours ago




3




3





It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

– Eric Duminil
6 hours ago





It's a great way to hide bugs! ts_folder is undefined for values larger than 0.95 or smaller than -0.85. Also, the result for -0.45 and -0.35 differ by 0.2.

– Eric Duminil
6 hours ago












11 Answers
11






active

oldest

votes


















25














Specific solution



There is no real general solution, but in your case you can use the following expression.



ts_folder = r'{:.1f}'.format(round(value, 1))


General solution



If you actually need some kind of generalization, notice that any non-linear pattern will cause trouble. Although, there is a way to shorten the code.



def classify(key, intervals):
for lo, hi, value in intervals:
if lo <= key < hi:
return value
else:
... # return a default value or None

# A list of tuples (lo, hi, key) which associates any value in the lo to hi interval to key
intervals = [
(value / 10 - 0.05, value / 10 + 0.05, r'{:.1f}'.format(value / 10))
for value in range(-9, 10)
]

value = -0.73

ts_folder = classify(value, intervals) # r'-0.7'


Notice that the above is still not totally safe from some float rounding error. You can add precision by manually typing down the intervals list instead of using a comprehension.






share|improve this answer





















  • 2





    r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

    – Aran-Fey
    12 hours ago






  • 1





    Note that the OP had if lo <=key < hi.

    – Martin Bonner
    8 hours ago






  • 1





    If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

    – Martin Bonner
    8 hours ago






  • 1





    Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

    – Eric Duminil
    6 hours ago











  • @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

    – Olivier Melançon
    4 hours ago



















10














The bisect module will do exactly the right lookup for finding the right bin from a list of breakpoints. In fact, the example in the documentation is exactly a case like this:




The bisect() function is generally useful for categorizing numeric data. This example uses bisect() to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an ‘A’, 75..84 is a ‘B’, etc.




>>> grades = "FEDCBA"
>>> breakpoints = [30, 44, 66, 75, 85]
>>> from bisect import bisect
>>> def grade(total):
... return grades[bisect(breakpoints, total)]
>>> grade(66)
'C'
>>> map(grade, [33, 99, 77, 44, 12, 88])
['E', 'A', 'B', 'D', 'F', 'A']


Instead of a string for the value lookups, you'd want a list of strings for the exact folder names you need for each range of values. For example:



breakpoints = [-0.85, -0.75, -0.65]
folders = [r'-0.9', r'-0.8', r'-0.7']
foldername = folders[bisect(breakpoints, -0.72)]


If you can automate even part of this table generation (using round(), or something similar), of course you should.






share|improve this answer































    7














    All answers revolve around rounding, which seems to be fine in this case, but just for the sake of argument I'd like to also point out a cool python use of dictionaries which is often described as an alternative to other languages switch(es) and that in turn allow for arbitrary values.



    ranges = {
    (-0.85, -0.95): r'-0.9',
    (-0.75, -0.85): r'-0.8',
    (-0.65, -0.75): r'-0.7',
    (-0.55, -0.65): r'-0.6'
    ...
    }

    def classify (value):
    for (ceiling, floor), rounded_value in ranges.items():
    if floor <= value < ceiling:
    return rounded_value


    Output:



    >>> classify(-0.78)
    -0.8





    share|improve this answer





















    • 15





      In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

      – bruno desthuilliers
      11 hours ago






    • 1





      @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

      – Arthur Tacca
      9 hours ago



















    5














    Why not just use the round() built-in ?



    ts_folder = "\" + str(round(value + 1e-16, 1))


    (The +1e-16 etc is because floats like .15 are by default rounded to .1, not .2)



    More on round()






    share|improve this answer


























    • It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

      – Eric Duminil
      6 hours ago













    • Oh my bad, should be good now

      – Fukiyel
      6 hours ago



















    3














    One of the first rules with a block of code like this, is to always make the comparisons be in the same direction. So instead of



        elif value < -0.75 and value >= -0.85:


    write



        elif -0.85 <= value and value < -0.75:


    At this point you can observe that python allows chaining of comparisons, so you can write:



        elif -0.85 <= value < -0.75:


    Which is an improvement itself. Alternatively, you can observe this is an ordered list of comparisons, so if you add in an initial comparisons, you can just write



        if value < -0.95:
    ts_folder = ''
    elif value < -0.85:
    ts_folder = r'-0.9'
    elif value < -0.75:
    ts_folder = r'-0.8'
    elif value < -0.65:
    ts_folder = r'-0.7'
    elif value < -0.55:
    ts_folder = r'-0.6'
    elif value < -0.45:
    ts_folder = r'-0.5'
    elif value < -0.35:
    ts_folder = r'-0.4'
    elif value < -0.25:
    ts_folder = r'-0.3'
    elif value < -0.15:
    ts_folder = r'-0.2'
    elif value < -0.05:
    ts_folder = r'-0.1'
    elif value < 0.05:
    ts_folder = r'.0'
    elif value < 0.15:
    ts_folder = r'.1'
    elif value < 0.25:
    ts_folder = r'.2'
    elif value < 0.35:
    ts_folder = r'.3'
    elif value < 0.45:
    ts_folder = r'.4'
    elif value < 0.55:
    ts_folder = r'.5'
    elif value < 0.65:
    ts_folder = r'.6'
    elif value < 0.75:
    ts_folder = r'.7'
    elif value < 0.85:
    ts_folder = r'.8'
    elif value < 0.95:
    ts_folder = r'.9'
    else:
    ts_folder = ''


    That's still quite long, but a) it's a lot more readable; b) it has explicit code to handle value < -0.95 or 0.95 <= value






    share|improve this answer


























    • this is one of the most useful answers here

      – aaaaaa
      1 hour ago



















    2














    Actually in Python 3 .85 will be round to .8. As per the question .85 should be round to .9.



    Can you try the following:



    round2 = lambda x, y=None: round(x+1e-15, y)
    ts_folder = r'{}'.format(str(round2(value, 1)))


    Output:



    >>> round2(.85, 1)
    0.9
    >>> round2(-.85, 1)
    -0.8





    share|improve this answer































      2














      Take a look at the round() function in python. Maybe you can work it out without the if.



      With this function you can specify the number of digits you need to keep.
      For example :



      x = round(5.76543, 2)
      print(x)


      That code will print 5.77






      share|improve this answer





















      • 2





        Please try and answer with a clear example

        – AJS
        13 hours ago



















      1














      How about turning it into a loop?



      def classify(value):
      i = -5
      while i < 95:
      if value < (i + 10) / 100.0 and value >= i / 100.0:
      return '\' + repr((i + 5) / 100.0)
      i += 10


      it's not efficient by any means, but it's equivalent to what you have, just shorter.






      share|improve this answer
























      • You need to start at ` i = -95`, though.

        – Eric Duminil
        6 hours ago



















      1














      from decimal import Decimal

      def classify(value):
      number = Decimal(value)
      result = "%.2f" % (number)
      return Decimal(round(float(result), 2))





      share|improve this answer





















      • 3





        star imports are bad practice.

        – bruno desthuilliers
        11 hours ago



















      0














      You don't need the and value >= -.85 in elif value < -0.75 and value >= -0.85:; if the value isn't greater than or equal to -.85, then you won't reach the elif. You can also just turn all the elifs into if by having each one return immediately.



      In this case, since you have the boundaries at regular intervals, you can just round (in the general case of regular intervals, you may have to divide and then round, for instance if the intervals are at every three units, then you would divide the number by three and round). In the general case, it's faster to store the boundaries in a tree structure, and then do a binary search for where the item goes.



      Doing a binary search explicitly would be something like this:



      def classify(value):   
      if value < -.05:
      if value < -.45:
      if value < -.65:
      if value < -.85:
      if value < -.95:
      return None
      return r'-0.9'
      if value < -.75:
      return r'-0.8'
      return r'-0.7'
      ...


      Although this code is harder to read than yours, it runs in time logarithmic rather than linear with respect to the number of boundaries.



      If the number of items is significantly larger than the number of boundaries, it would probably be faster to actually create a tree of the items, and insert the boundaries.



      You could also create a list, sort it, and then look at the index. For instance, compare (sorted([(_-9.5)/10 for _ in range(20)]+[x]).index(x)-9)/10 to your function.






      share|improve this answer































        0














        Try something like this, if you don't like loops:



        def classify(value): 
        endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
        ts_folder = [ r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
        idx = [value >= end for end in endpts].index(False)
        if not idx:
        raise ValueError('Value outside of range')
        return ts_folder[idx-1]


        Of course, the loop is just "hidden" in the list comprehension.
        Obviously, in this example, it would be better to generate endpts and ts_fol programmatically rather than writing them all out, but you indicated that in the real situation the endpoints and values aren't so straightforward.



        This raises a ValueError if value ≥ 0.95 (because False is not found in the list comprehension) or if value < -0.95 (because then idx is 0); the original version raises a UnboundLocalError in these cases.



        You could also save three lines and skip a few comparisons by doing this:



        def classify(value):
        endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
        ts_fol = [ None, r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
        return next((ts for ts, end in zip(ts_fol, endpts) if value < end), None)


        This version returns None rather than raising exceptions for any value outside the bounds.






        share|improve this answer

























          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55180829%2fpython-if-else-code-style-for-reduced-code-for-rounding-floats%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          11 Answers
          11






          active

          oldest

          votes








          11 Answers
          11






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          25














          Specific solution



          There is no real general solution, but in your case you can use the following expression.



          ts_folder = r'{:.1f}'.format(round(value, 1))


          General solution



          If you actually need some kind of generalization, notice that any non-linear pattern will cause trouble. Although, there is a way to shorten the code.



          def classify(key, intervals):
          for lo, hi, value in intervals:
          if lo <= key < hi:
          return value
          else:
          ... # return a default value or None

          # A list of tuples (lo, hi, key) which associates any value in the lo to hi interval to key
          intervals = [
          (value / 10 - 0.05, value / 10 + 0.05, r'{:.1f}'.format(value / 10))
          for value in range(-9, 10)
          ]

          value = -0.73

          ts_folder = classify(value, intervals) # r'-0.7'


          Notice that the above is still not totally safe from some float rounding error. You can add precision by manually typing down the intervals list instead of using a comprehension.






          share|improve this answer





















          • 2





            r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

            – Aran-Fey
            12 hours ago






          • 1





            Note that the OP had if lo <=key < hi.

            – Martin Bonner
            8 hours ago






          • 1





            If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

            – Martin Bonner
            8 hours ago






          • 1





            Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

            – Eric Duminil
            6 hours ago











          • @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

            – Olivier Melançon
            4 hours ago
















          25














          Specific solution



          There is no real general solution, but in your case you can use the following expression.



          ts_folder = r'{:.1f}'.format(round(value, 1))


          General solution



          If you actually need some kind of generalization, notice that any non-linear pattern will cause trouble. Although, there is a way to shorten the code.



          def classify(key, intervals):
          for lo, hi, value in intervals:
          if lo <= key < hi:
          return value
          else:
          ... # return a default value or None

          # A list of tuples (lo, hi, key) which associates any value in the lo to hi interval to key
          intervals = [
          (value / 10 - 0.05, value / 10 + 0.05, r'{:.1f}'.format(value / 10))
          for value in range(-9, 10)
          ]

          value = -0.73

          ts_folder = classify(value, intervals) # r'-0.7'


          Notice that the above is still not totally safe from some float rounding error. You can add precision by manually typing down the intervals list instead of using a comprehension.






          share|improve this answer





















          • 2





            r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

            – Aran-Fey
            12 hours ago






          • 1





            Note that the OP had if lo <=key < hi.

            – Martin Bonner
            8 hours ago






          • 1





            If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

            – Martin Bonner
            8 hours ago






          • 1





            Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

            – Eric Duminil
            6 hours ago











          • @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

            – Olivier Melançon
            4 hours ago














          25












          25








          25







          Specific solution



          There is no real general solution, but in your case you can use the following expression.



          ts_folder = r'{:.1f}'.format(round(value, 1))


          General solution



          If you actually need some kind of generalization, notice that any non-linear pattern will cause trouble. Although, there is a way to shorten the code.



          def classify(key, intervals):
          for lo, hi, value in intervals:
          if lo <= key < hi:
          return value
          else:
          ... # return a default value or None

          # A list of tuples (lo, hi, key) which associates any value in the lo to hi interval to key
          intervals = [
          (value / 10 - 0.05, value / 10 + 0.05, r'{:.1f}'.format(value / 10))
          for value in range(-9, 10)
          ]

          value = -0.73

          ts_folder = classify(value, intervals) # r'-0.7'


          Notice that the above is still not totally safe from some float rounding error. You can add precision by manually typing down the intervals list instead of using a comprehension.






          share|improve this answer















          Specific solution



          There is no real general solution, but in your case you can use the following expression.



          ts_folder = r'{:.1f}'.format(round(value, 1))


          General solution



          If you actually need some kind of generalization, notice that any non-linear pattern will cause trouble. Although, there is a way to shorten the code.



          def classify(key, intervals):
          for lo, hi, value in intervals:
          if lo <= key < hi:
          return value
          else:
          ... # return a default value or None

          # A list of tuples (lo, hi, key) which associates any value in the lo to hi interval to key
          intervals = [
          (value / 10 - 0.05, value / 10 + 0.05, r'{:.1f}'.format(value / 10))
          for value in range(-9, 10)
          ]

          value = -0.73

          ts_folder = classify(value, intervals) # r'-0.7'


          Notice that the above is still not totally safe from some float rounding error. You can add precision by manually typing down the intervals list instead of using a comprehension.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 4 hours ago

























          answered 12 hours ago









          Olivier MelançonOlivier Melançon

          13.9k22042




          13.9k22042








          • 2





            r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

            – Aran-Fey
            12 hours ago






          • 1





            Note that the OP had if lo <=key < hi.

            – Martin Bonner
            8 hours ago






          • 1





            If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

            – Martin Bonner
            8 hours ago






          • 1





            Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

            – Eric Duminil
            6 hours ago











          • @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

            – Olivier Melançon
            4 hours ago














          • 2





            r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

            – Aran-Fey
            12 hours ago






          • 1





            Note that the OP had if lo <=key < hi.

            – Martin Bonner
            8 hours ago






          • 1





            If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

            – Martin Bonner
            8 hours ago






          • 1





            Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

            – Eric Duminil
            6 hours ago











          • @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

            – Olivier Melançon
            4 hours ago








          2




          2





          r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

          – Aran-Fey
          12 hours ago





          r '{}'.format(str(folder_value)[:3 if folder_value >= 0 else 4]) can be simplified to r'{:.1f}'.format(folder_value).

          – Aran-Fey
          12 hours ago




          1




          1





          Note that the OP had if lo <=key < hi.

          – Martin Bonner
          8 hours ago





          Note that the OP had if lo <=key < hi.

          – Martin Bonner
          8 hours ago




          1




          1





          If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

          – Martin Bonner
          8 hours ago





          If the intervals are supposed to be contiguous, you can require that they are supplied sorted (low to high), and then just have the intervals be (hi, value), and then the loop becomes for hi, value in intervals: if key < hi: return value

          – Martin Bonner
          8 hours ago




          1




          1





          Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

          – Eric Duminil
          6 hours ago





          Floats comparison are tricky. On my computer, your specific solution returns different values for [-0.75, -0.65, -0.55, -0.45, -0.05, -0.04, -0.03, -0.02, -0.01, 0.15, 0.25, 0.35, 0.85] compared to OP's code.

          – Eric Duminil
          6 hours ago













          @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

          – Olivier Melançon
          4 hours ago





          @EricDuminill yes, that is why I suggest providing them as literals, without using a list-comprehension.

          – Olivier Melançon
          4 hours ago













          10














          The bisect module will do exactly the right lookup for finding the right bin from a list of breakpoints. In fact, the example in the documentation is exactly a case like this:




          The bisect() function is generally useful for categorizing numeric data. This example uses bisect() to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an ‘A’, 75..84 is a ‘B’, etc.




          >>> grades = "FEDCBA"
          >>> breakpoints = [30, 44, 66, 75, 85]
          >>> from bisect import bisect
          >>> def grade(total):
          ... return grades[bisect(breakpoints, total)]
          >>> grade(66)
          'C'
          >>> map(grade, [33, 99, 77, 44, 12, 88])
          ['E', 'A', 'B', 'D', 'F', 'A']


          Instead of a string for the value lookups, you'd want a list of strings for the exact folder names you need for each range of values. For example:



          breakpoints = [-0.85, -0.75, -0.65]
          folders = [r'-0.9', r'-0.8', r'-0.7']
          foldername = folders[bisect(breakpoints, -0.72)]


          If you can automate even part of this table generation (using round(), or something similar), of course you should.






          share|improve this answer




























            10














            The bisect module will do exactly the right lookup for finding the right bin from a list of breakpoints. In fact, the example in the documentation is exactly a case like this:




            The bisect() function is generally useful for categorizing numeric data. This example uses bisect() to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an ‘A’, 75..84 is a ‘B’, etc.




            >>> grades = "FEDCBA"
            >>> breakpoints = [30, 44, 66, 75, 85]
            >>> from bisect import bisect
            >>> def grade(total):
            ... return grades[bisect(breakpoints, total)]
            >>> grade(66)
            'C'
            >>> map(grade, [33, 99, 77, 44, 12, 88])
            ['E', 'A', 'B', 'D', 'F', 'A']


            Instead of a string for the value lookups, you'd want a list of strings for the exact folder names you need for each range of values. For example:



            breakpoints = [-0.85, -0.75, -0.65]
            folders = [r'-0.9', r'-0.8', r'-0.7']
            foldername = folders[bisect(breakpoints, -0.72)]


            If you can automate even part of this table generation (using round(), or something similar), of course you should.






            share|improve this answer


























              10












              10








              10







              The bisect module will do exactly the right lookup for finding the right bin from a list of breakpoints. In fact, the example in the documentation is exactly a case like this:




              The bisect() function is generally useful for categorizing numeric data. This example uses bisect() to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an ‘A’, 75..84 is a ‘B’, etc.




              >>> grades = "FEDCBA"
              >>> breakpoints = [30, 44, 66, 75, 85]
              >>> from bisect import bisect
              >>> def grade(total):
              ... return grades[bisect(breakpoints, total)]
              >>> grade(66)
              'C'
              >>> map(grade, [33, 99, 77, 44, 12, 88])
              ['E', 'A', 'B', 'D', 'F', 'A']


              Instead of a string for the value lookups, you'd want a list of strings for the exact folder names you need for each range of values. For example:



              breakpoints = [-0.85, -0.75, -0.65]
              folders = [r'-0.9', r'-0.8', r'-0.7']
              foldername = folders[bisect(breakpoints, -0.72)]


              If you can automate even part of this table generation (using round(), or something similar), of course you should.






              share|improve this answer













              The bisect module will do exactly the right lookup for finding the right bin from a list of breakpoints. In fact, the example in the documentation is exactly a case like this:




              The bisect() function is generally useful for categorizing numeric data. This example uses bisect() to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an ‘A’, 75..84 is a ‘B’, etc.




              >>> grades = "FEDCBA"
              >>> breakpoints = [30, 44, 66, 75, 85]
              >>> from bisect import bisect
              >>> def grade(total):
              ... return grades[bisect(breakpoints, total)]
              >>> grade(66)
              'C'
              >>> map(grade, [33, 99, 77, 44, 12, 88])
              ['E', 'A', 'B', 'D', 'F', 'A']


              Instead of a string for the value lookups, you'd want a list of strings for the exact folder names you need for each range of values. For example:



              breakpoints = [-0.85, -0.75, -0.65]
              folders = [r'-0.9', r'-0.8', r'-0.7']
              foldername = folders[bisect(breakpoints, -0.72)]


              If you can automate even part of this table generation (using round(), or something similar), of course you should.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 6 hours ago









              PeterPeter

              11.5k1846




              11.5k1846























                  7














                  All answers revolve around rounding, which seems to be fine in this case, but just for the sake of argument I'd like to also point out a cool python use of dictionaries which is often described as an alternative to other languages switch(es) and that in turn allow for arbitrary values.



                  ranges = {
                  (-0.85, -0.95): r'-0.9',
                  (-0.75, -0.85): r'-0.8',
                  (-0.65, -0.75): r'-0.7',
                  (-0.55, -0.65): r'-0.6'
                  ...
                  }

                  def classify (value):
                  for (ceiling, floor), rounded_value in ranges.items():
                  if floor <= value < ceiling:
                  return rounded_value


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer





















                  • 15





                    In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                    – bruno desthuilliers
                    11 hours ago






                  • 1





                    @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                    – Arthur Tacca
                    9 hours ago
















                  7














                  All answers revolve around rounding, which seems to be fine in this case, but just for the sake of argument I'd like to also point out a cool python use of dictionaries which is often described as an alternative to other languages switch(es) and that in turn allow for arbitrary values.



                  ranges = {
                  (-0.85, -0.95): r'-0.9',
                  (-0.75, -0.85): r'-0.8',
                  (-0.65, -0.75): r'-0.7',
                  (-0.55, -0.65): r'-0.6'
                  ...
                  }

                  def classify (value):
                  for (ceiling, floor), rounded_value in ranges.items():
                  if floor <= value < ceiling:
                  return rounded_value


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer





















                  • 15





                    In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                    – bruno desthuilliers
                    11 hours ago






                  • 1





                    @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                    – Arthur Tacca
                    9 hours ago














                  7












                  7








                  7







                  All answers revolve around rounding, which seems to be fine in this case, but just for the sake of argument I'd like to also point out a cool python use of dictionaries which is often described as an alternative to other languages switch(es) and that in turn allow for arbitrary values.



                  ranges = {
                  (-0.85, -0.95): r'-0.9',
                  (-0.75, -0.85): r'-0.8',
                  (-0.65, -0.75): r'-0.7',
                  (-0.55, -0.65): r'-0.6'
                  ...
                  }

                  def classify (value):
                  for (ceiling, floor), rounded_value in ranges.items():
                  if floor <= value < ceiling:
                  return rounded_value


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer















                  All answers revolve around rounding, which seems to be fine in this case, but just for the sake of argument I'd like to also point out a cool python use of dictionaries which is often described as an alternative to other languages switch(es) and that in turn allow for arbitrary values.



                  ranges = {
                  (-0.85, -0.95): r'-0.9',
                  (-0.75, -0.85): r'-0.8',
                  (-0.65, -0.75): r'-0.7',
                  (-0.55, -0.65): r'-0.6'
                  ...
                  }

                  def classify (value):
                  for (ceiling, floor), rounded_value in ranges.items():
                  if floor <= value < ceiling:
                  return rounded_value


                  Output:



                  >>> classify(-0.78)
                  -0.8






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 9 hours ago









                  chepner

                  257k34247339




                  257k34247339










                  answered 12 hours ago









                  Hirabayashi TaroHirabayashi Taro

                  533311




                  533311








                  • 15





                    In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                    – bruno desthuilliers
                    11 hours ago






                  • 1





                    @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                    – Arthur Tacca
                    9 hours ago














                  • 15





                    In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                    – bruno desthuilliers
                    11 hours ago






                  • 1





                    @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                    – Arthur Tacca
                    9 hours ago








                  15




                  15





                  In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                  – bruno desthuilliers
                  11 hours ago





                  In this case you're NOT using the "dict dispatch" trick - you're doing a sequential scan, so you'd get the exact same result with a list of (start, stop, val) tuples (but with the added overhead of creating a dict and doing a useless __getitem__ access).

                  – bruno desthuilliers
                  11 hours ago




                  1




                  1





                  @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                  – Arthur Tacca
                  9 hours ago





                  @chepner By editing this code you have made it not work; it indexes into ranges with current_value which is not defined (because you deleted it).

                  – Arthur Tacca
                  9 hours ago











                  5














                  Why not just use the round() built-in ?



                  ts_folder = "\" + str(round(value + 1e-16, 1))


                  (The +1e-16 etc is because floats like .15 are by default rounded to .1, not .2)



                  More on round()






                  share|improve this answer


























                  • It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                    – Eric Duminil
                    6 hours ago













                  • Oh my bad, should be good now

                    – Fukiyel
                    6 hours ago
















                  5














                  Why not just use the round() built-in ?



                  ts_folder = "\" + str(round(value + 1e-16, 1))


                  (The +1e-16 etc is because floats like .15 are by default rounded to .1, not .2)



                  More on round()






                  share|improve this answer


























                  • It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                    – Eric Duminil
                    6 hours ago













                  • Oh my bad, should be good now

                    – Fukiyel
                    6 hours ago














                  5












                  5








                  5







                  Why not just use the round() built-in ?



                  ts_folder = "\" + str(round(value + 1e-16, 1))


                  (The +1e-16 etc is because floats like .15 are by default rounded to .1, not .2)



                  More on round()






                  share|improve this answer















                  Why not just use the round() built-in ?



                  ts_folder = "\" + str(round(value + 1e-16, 1))


                  (The +1e-16 etc is because floats like .15 are by default rounded to .1, not .2)



                  More on round()







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 6 hours ago

























                  answered 13 hours ago









                  FukiyelFukiyel

                  902216




                  902216













                  • It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                    – Eric Duminil
                    6 hours ago













                  • Oh my bad, should be good now

                    – Fukiyel
                    6 hours ago



















                  • It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                    – Eric Duminil
                    6 hours ago













                  • Oh my bad, should be good now

                    – Fukiyel
                    6 hours ago

















                  It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                  – Eric Duminil
                  6 hours ago







                  It doesn't seem to work for [-0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, -0.04, -0.03, -0.02, -0.01, 0.0], compared to OP's code. I'm not sure if it's a bug or a feature.

                  – Eric Duminil
                  6 hours ago















                  Oh my bad, should be good now

                  – Fukiyel
                  6 hours ago





                  Oh my bad, should be good now

                  – Fukiyel
                  6 hours ago











                  3














                  One of the first rules with a block of code like this, is to always make the comparisons be in the same direction. So instead of



                      elif value < -0.75 and value >= -0.85:


                  write



                      elif -0.85 <= value and value < -0.75:


                  At this point you can observe that python allows chaining of comparisons, so you can write:



                      elif -0.85 <= value < -0.75:


                  Which is an improvement itself. Alternatively, you can observe this is an ordered list of comparisons, so if you add in an initial comparisons, you can just write



                      if value < -0.95:
                  ts_folder = ''
                  elif value < -0.85:
                  ts_folder = r'-0.9'
                  elif value < -0.75:
                  ts_folder = r'-0.8'
                  elif value < -0.65:
                  ts_folder = r'-0.7'
                  elif value < -0.55:
                  ts_folder = r'-0.6'
                  elif value < -0.45:
                  ts_folder = r'-0.5'
                  elif value < -0.35:
                  ts_folder = r'-0.4'
                  elif value < -0.25:
                  ts_folder = r'-0.3'
                  elif value < -0.15:
                  ts_folder = r'-0.2'
                  elif value < -0.05:
                  ts_folder = r'-0.1'
                  elif value < 0.05:
                  ts_folder = r'.0'
                  elif value < 0.15:
                  ts_folder = r'.1'
                  elif value < 0.25:
                  ts_folder = r'.2'
                  elif value < 0.35:
                  ts_folder = r'.3'
                  elif value < 0.45:
                  ts_folder = r'.4'
                  elif value < 0.55:
                  ts_folder = r'.5'
                  elif value < 0.65:
                  ts_folder = r'.6'
                  elif value < 0.75:
                  ts_folder = r'.7'
                  elif value < 0.85:
                  ts_folder = r'.8'
                  elif value < 0.95:
                  ts_folder = r'.9'
                  else:
                  ts_folder = ''


                  That's still quite long, but a) it's a lot more readable; b) it has explicit code to handle value < -0.95 or 0.95 <= value






                  share|improve this answer


























                  • this is one of the most useful answers here

                    – aaaaaa
                    1 hour ago
















                  3














                  One of the first rules with a block of code like this, is to always make the comparisons be in the same direction. So instead of



                      elif value < -0.75 and value >= -0.85:


                  write



                      elif -0.85 <= value and value < -0.75:


                  At this point you can observe that python allows chaining of comparisons, so you can write:



                      elif -0.85 <= value < -0.75:


                  Which is an improvement itself. Alternatively, you can observe this is an ordered list of comparisons, so if you add in an initial comparisons, you can just write



                      if value < -0.95:
                  ts_folder = ''
                  elif value < -0.85:
                  ts_folder = r'-0.9'
                  elif value < -0.75:
                  ts_folder = r'-0.8'
                  elif value < -0.65:
                  ts_folder = r'-0.7'
                  elif value < -0.55:
                  ts_folder = r'-0.6'
                  elif value < -0.45:
                  ts_folder = r'-0.5'
                  elif value < -0.35:
                  ts_folder = r'-0.4'
                  elif value < -0.25:
                  ts_folder = r'-0.3'
                  elif value < -0.15:
                  ts_folder = r'-0.2'
                  elif value < -0.05:
                  ts_folder = r'-0.1'
                  elif value < 0.05:
                  ts_folder = r'.0'
                  elif value < 0.15:
                  ts_folder = r'.1'
                  elif value < 0.25:
                  ts_folder = r'.2'
                  elif value < 0.35:
                  ts_folder = r'.3'
                  elif value < 0.45:
                  ts_folder = r'.4'
                  elif value < 0.55:
                  ts_folder = r'.5'
                  elif value < 0.65:
                  ts_folder = r'.6'
                  elif value < 0.75:
                  ts_folder = r'.7'
                  elif value < 0.85:
                  ts_folder = r'.8'
                  elif value < 0.95:
                  ts_folder = r'.9'
                  else:
                  ts_folder = ''


                  That's still quite long, but a) it's a lot more readable; b) it has explicit code to handle value < -0.95 or 0.95 <= value






                  share|improve this answer


























                  • this is one of the most useful answers here

                    – aaaaaa
                    1 hour ago














                  3












                  3








                  3







                  One of the first rules with a block of code like this, is to always make the comparisons be in the same direction. So instead of



                      elif value < -0.75 and value >= -0.85:


                  write



                      elif -0.85 <= value and value < -0.75:


                  At this point you can observe that python allows chaining of comparisons, so you can write:



                      elif -0.85 <= value < -0.75:


                  Which is an improvement itself. Alternatively, you can observe this is an ordered list of comparisons, so if you add in an initial comparisons, you can just write



                      if value < -0.95:
                  ts_folder = ''
                  elif value < -0.85:
                  ts_folder = r'-0.9'
                  elif value < -0.75:
                  ts_folder = r'-0.8'
                  elif value < -0.65:
                  ts_folder = r'-0.7'
                  elif value < -0.55:
                  ts_folder = r'-0.6'
                  elif value < -0.45:
                  ts_folder = r'-0.5'
                  elif value < -0.35:
                  ts_folder = r'-0.4'
                  elif value < -0.25:
                  ts_folder = r'-0.3'
                  elif value < -0.15:
                  ts_folder = r'-0.2'
                  elif value < -0.05:
                  ts_folder = r'-0.1'
                  elif value < 0.05:
                  ts_folder = r'.0'
                  elif value < 0.15:
                  ts_folder = r'.1'
                  elif value < 0.25:
                  ts_folder = r'.2'
                  elif value < 0.35:
                  ts_folder = r'.3'
                  elif value < 0.45:
                  ts_folder = r'.4'
                  elif value < 0.55:
                  ts_folder = r'.5'
                  elif value < 0.65:
                  ts_folder = r'.6'
                  elif value < 0.75:
                  ts_folder = r'.7'
                  elif value < 0.85:
                  ts_folder = r'.8'
                  elif value < 0.95:
                  ts_folder = r'.9'
                  else:
                  ts_folder = ''


                  That's still quite long, but a) it's a lot more readable; b) it has explicit code to handle value < -0.95 or 0.95 <= value






                  share|improve this answer















                  One of the first rules with a block of code like this, is to always make the comparisons be in the same direction. So instead of



                      elif value < -0.75 and value >= -0.85:


                  write



                      elif -0.85 <= value and value < -0.75:


                  At this point you can observe that python allows chaining of comparisons, so you can write:



                      elif -0.85 <= value < -0.75:


                  Which is an improvement itself. Alternatively, you can observe this is an ordered list of comparisons, so if you add in an initial comparisons, you can just write



                      if value < -0.95:
                  ts_folder = ''
                  elif value < -0.85:
                  ts_folder = r'-0.9'
                  elif value < -0.75:
                  ts_folder = r'-0.8'
                  elif value < -0.65:
                  ts_folder = r'-0.7'
                  elif value < -0.55:
                  ts_folder = r'-0.6'
                  elif value < -0.45:
                  ts_folder = r'-0.5'
                  elif value < -0.35:
                  ts_folder = r'-0.4'
                  elif value < -0.25:
                  ts_folder = r'-0.3'
                  elif value < -0.15:
                  ts_folder = r'-0.2'
                  elif value < -0.05:
                  ts_folder = r'-0.1'
                  elif value < 0.05:
                  ts_folder = r'.0'
                  elif value < 0.15:
                  ts_folder = r'.1'
                  elif value < 0.25:
                  ts_folder = r'.2'
                  elif value < 0.35:
                  ts_folder = r'.3'
                  elif value < 0.45:
                  ts_folder = r'.4'
                  elif value < 0.55:
                  ts_folder = r'.5'
                  elif value < 0.65:
                  ts_folder = r'.6'
                  elif value < 0.75:
                  ts_folder = r'.7'
                  elif value < 0.85:
                  ts_folder = r'.8'
                  elif value < 0.95:
                  ts_folder = r'.9'
                  else:
                  ts_folder = ''


                  That's still quite long, but a) it's a lot more readable; b) it has explicit code to handle value < -0.95 or 0.95 <= value







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 6 hours ago









                  Eric Towers

                  3,6191015




                  3,6191015










                  answered 8 hours ago









                  Martin BonnerMartin Bonner

                  23.5k33266




                  23.5k33266













                  • this is one of the most useful answers here

                    – aaaaaa
                    1 hour ago



















                  • this is one of the most useful answers here

                    – aaaaaa
                    1 hour ago

















                  this is one of the most useful answers here

                  – aaaaaa
                  1 hour ago





                  this is one of the most useful answers here

                  – aaaaaa
                  1 hour ago











                  2














                  Actually in Python 3 .85 will be round to .8. As per the question .85 should be round to .9.



                  Can you try the following:



                  round2 = lambda x, y=None: round(x+1e-15, y)
                  ts_folder = r'{}'.format(str(round2(value, 1)))


                  Output:



                  >>> round2(.85, 1)
                  0.9
                  >>> round2(-.85, 1)
                  -0.8





                  share|improve this answer




























                    2














                    Actually in Python 3 .85 will be round to .8. As per the question .85 should be round to .9.



                    Can you try the following:



                    round2 = lambda x, y=None: round(x+1e-15, y)
                    ts_folder = r'{}'.format(str(round2(value, 1)))


                    Output:



                    >>> round2(.85, 1)
                    0.9
                    >>> round2(-.85, 1)
                    -0.8





                    share|improve this answer


























                      2












                      2








                      2







                      Actually in Python 3 .85 will be round to .8. As per the question .85 should be round to .9.



                      Can you try the following:



                      round2 = lambda x, y=None: round(x+1e-15, y)
                      ts_folder = r'{}'.format(str(round2(value, 1)))


                      Output:



                      >>> round2(.85, 1)
                      0.9
                      >>> round2(-.85, 1)
                      -0.8





                      share|improve this answer













                      Actually in Python 3 .85 will be round to .8. As per the question .85 should be round to .9.



                      Can you try the following:



                      round2 = lambda x, y=None: round(x+1e-15, y)
                      ts_folder = r'{}'.format(str(round2(value, 1)))


                      Output:



                      >>> round2(.85, 1)
                      0.9
                      >>> round2(-.85, 1)
                      -0.8






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 12 hours ago









                      JerilJeril

                      2,4411735




                      2,4411735























                          2














                          Take a look at the round() function in python. Maybe you can work it out without the if.



                          With this function you can specify the number of digits you need to keep.
                          For example :



                          x = round(5.76543, 2)
                          print(x)


                          That code will print 5.77






                          share|improve this answer





















                          • 2





                            Please try and answer with a clear example

                            – AJS
                            13 hours ago
















                          2














                          Take a look at the round() function in python. Maybe you can work it out without the if.



                          With this function you can specify the number of digits you need to keep.
                          For example :



                          x = round(5.76543, 2)
                          print(x)


                          That code will print 5.77






                          share|improve this answer





















                          • 2





                            Please try and answer with a clear example

                            – AJS
                            13 hours ago














                          2












                          2








                          2







                          Take a look at the round() function in python. Maybe you can work it out without the if.



                          With this function you can specify the number of digits you need to keep.
                          For example :



                          x = round(5.76543, 2)
                          print(x)


                          That code will print 5.77






                          share|improve this answer















                          Take a look at the round() function in python. Maybe you can work it out without the if.



                          With this function you can specify the number of digits you need to keep.
                          For example :



                          x = round(5.76543, 2)
                          print(x)


                          That code will print 5.77







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 4 hours ago









                          Olivier Melançon

                          13.9k22042




                          13.9k22042










                          answered 13 hours ago









                          MelKoutchMelKoutch

                          575




                          575








                          • 2





                            Please try and answer with a clear example

                            – AJS
                            13 hours ago














                          • 2





                            Please try and answer with a clear example

                            – AJS
                            13 hours ago








                          2




                          2





                          Please try and answer with a clear example

                          – AJS
                          13 hours ago





                          Please try and answer with a clear example

                          – AJS
                          13 hours ago











                          1














                          How about turning it into a loop?



                          def classify(value):
                          i = -5
                          while i < 95:
                          if value < (i + 10) / 100.0 and value >= i / 100.0:
                          return '\' + repr((i + 5) / 100.0)
                          i += 10


                          it's not efficient by any means, but it's equivalent to what you have, just shorter.






                          share|improve this answer
























                          • You need to start at ` i = -95`, though.

                            – Eric Duminil
                            6 hours ago
















                          1














                          How about turning it into a loop?



                          def classify(value):
                          i = -5
                          while i < 95:
                          if value < (i + 10) / 100.0 and value >= i / 100.0:
                          return '\' + repr((i + 5) / 100.0)
                          i += 10


                          it's not efficient by any means, but it's equivalent to what you have, just shorter.






                          share|improve this answer
























                          • You need to start at ` i = -95`, though.

                            – Eric Duminil
                            6 hours ago














                          1












                          1








                          1







                          How about turning it into a loop?



                          def classify(value):
                          i = -5
                          while i < 95:
                          if value < (i + 10) / 100.0 and value >= i / 100.0:
                          return '\' + repr((i + 5) / 100.0)
                          i += 10


                          it's not efficient by any means, but it's equivalent to what you have, just shorter.






                          share|improve this answer













                          How about turning it into a loop?



                          def classify(value):
                          i = -5
                          while i < 95:
                          if value < (i + 10) / 100.0 and value >= i / 100.0:
                          return '\' + repr((i + 5) / 100.0)
                          i += 10


                          it's not efficient by any means, but it's equivalent to what you have, just shorter.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 11 hours ago









                          MehrdadMehrdad

                          129k90415758




                          129k90415758













                          • You need to start at ` i = -95`, though.

                            – Eric Duminil
                            6 hours ago



















                          • You need to start at ` i = -95`, though.

                            – Eric Duminil
                            6 hours ago

















                          You need to start at ` i = -95`, though.

                          – Eric Duminil
                          6 hours ago





                          You need to start at ` i = -95`, though.

                          – Eric Duminil
                          6 hours ago











                          1














                          from decimal import Decimal

                          def classify(value):
                          number = Decimal(value)
                          result = "%.2f" % (number)
                          return Decimal(round(float(result), 2))





                          share|improve this answer





















                          • 3





                            star imports are bad practice.

                            – bruno desthuilliers
                            11 hours ago
















                          1














                          from decimal import Decimal

                          def classify(value):
                          number = Decimal(value)
                          result = "%.2f" % (number)
                          return Decimal(round(float(result), 2))





                          share|improve this answer





















                          • 3





                            star imports are bad practice.

                            – bruno desthuilliers
                            11 hours ago














                          1












                          1








                          1







                          from decimal import Decimal

                          def classify(value):
                          number = Decimal(value)
                          result = "%.2f" % (number)
                          return Decimal(round(float(result), 2))





                          share|improve this answer















                          from decimal import Decimal

                          def classify(value):
                          number = Decimal(value)
                          result = "%.2f" % (number)
                          return Decimal(round(float(result), 2))






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 5 hours ago









                          wizzwizz4

                          3,60011637




                          3,60011637










                          answered 12 hours ago









                          Asif AkhtarAsif Akhtar

                          78110




                          78110








                          • 3





                            star imports are bad practice.

                            – bruno desthuilliers
                            11 hours ago














                          • 3





                            star imports are bad practice.

                            – bruno desthuilliers
                            11 hours ago








                          3




                          3





                          star imports are bad practice.

                          – bruno desthuilliers
                          11 hours ago





                          star imports are bad practice.

                          – bruno desthuilliers
                          11 hours ago











                          0














                          You don't need the and value >= -.85 in elif value < -0.75 and value >= -0.85:; if the value isn't greater than or equal to -.85, then you won't reach the elif. You can also just turn all the elifs into if by having each one return immediately.



                          In this case, since you have the boundaries at regular intervals, you can just round (in the general case of regular intervals, you may have to divide and then round, for instance if the intervals are at every three units, then you would divide the number by three and round). In the general case, it's faster to store the boundaries in a tree structure, and then do a binary search for where the item goes.



                          Doing a binary search explicitly would be something like this:



                          def classify(value):   
                          if value < -.05:
                          if value < -.45:
                          if value < -.65:
                          if value < -.85:
                          if value < -.95:
                          return None
                          return r'-0.9'
                          if value < -.75:
                          return r'-0.8'
                          return r'-0.7'
                          ...


                          Although this code is harder to read than yours, it runs in time logarithmic rather than linear with respect to the number of boundaries.



                          If the number of items is significantly larger than the number of boundaries, it would probably be faster to actually create a tree of the items, and insert the boundaries.



                          You could also create a list, sort it, and then look at the index. For instance, compare (sorted([(_-9.5)/10 for _ in range(20)]+[x]).index(x)-9)/10 to your function.






                          share|improve this answer




























                            0














                            You don't need the and value >= -.85 in elif value < -0.75 and value >= -0.85:; if the value isn't greater than or equal to -.85, then you won't reach the elif. You can also just turn all the elifs into if by having each one return immediately.



                            In this case, since you have the boundaries at regular intervals, you can just round (in the general case of regular intervals, you may have to divide and then round, for instance if the intervals are at every three units, then you would divide the number by three and round). In the general case, it's faster to store the boundaries in a tree structure, and then do a binary search for where the item goes.



                            Doing a binary search explicitly would be something like this:



                            def classify(value):   
                            if value < -.05:
                            if value < -.45:
                            if value < -.65:
                            if value < -.85:
                            if value < -.95:
                            return None
                            return r'-0.9'
                            if value < -.75:
                            return r'-0.8'
                            return r'-0.7'
                            ...


                            Although this code is harder to read than yours, it runs in time logarithmic rather than linear with respect to the number of boundaries.



                            If the number of items is significantly larger than the number of boundaries, it would probably be faster to actually create a tree of the items, and insert the boundaries.



                            You could also create a list, sort it, and then look at the index. For instance, compare (sorted([(_-9.5)/10 for _ in range(20)]+[x]).index(x)-9)/10 to your function.






                            share|improve this answer


























                              0












                              0








                              0







                              You don't need the and value >= -.85 in elif value < -0.75 and value >= -0.85:; if the value isn't greater than or equal to -.85, then you won't reach the elif. You can also just turn all the elifs into if by having each one return immediately.



                              In this case, since you have the boundaries at regular intervals, you can just round (in the general case of regular intervals, you may have to divide and then round, for instance if the intervals are at every three units, then you would divide the number by three and round). In the general case, it's faster to store the boundaries in a tree structure, and then do a binary search for where the item goes.



                              Doing a binary search explicitly would be something like this:



                              def classify(value):   
                              if value < -.05:
                              if value < -.45:
                              if value < -.65:
                              if value < -.85:
                              if value < -.95:
                              return None
                              return r'-0.9'
                              if value < -.75:
                              return r'-0.8'
                              return r'-0.7'
                              ...


                              Although this code is harder to read than yours, it runs in time logarithmic rather than linear with respect to the number of boundaries.



                              If the number of items is significantly larger than the number of boundaries, it would probably be faster to actually create a tree of the items, and insert the boundaries.



                              You could also create a list, sort it, and then look at the index. For instance, compare (sorted([(_-9.5)/10 for _ in range(20)]+[x]).index(x)-9)/10 to your function.






                              share|improve this answer













                              You don't need the and value >= -.85 in elif value < -0.75 and value >= -0.85:; if the value isn't greater than or equal to -.85, then you won't reach the elif. You can also just turn all the elifs into if by having each one return immediately.



                              In this case, since you have the boundaries at regular intervals, you can just round (in the general case of regular intervals, you may have to divide and then round, for instance if the intervals are at every three units, then you would divide the number by three and round). In the general case, it's faster to store the boundaries in a tree structure, and then do a binary search for where the item goes.



                              Doing a binary search explicitly would be something like this:



                              def classify(value):   
                              if value < -.05:
                              if value < -.45:
                              if value < -.65:
                              if value < -.85:
                              if value < -.95:
                              return None
                              return r'-0.9'
                              if value < -.75:
                              return r'-0.8'
                              return r'-0.7'
                              ...


                              Although this code is harder to read than yours, it runs in time logarithmic rather than linear with respect to the number of boundaries.



                              If the number of items is significantly larger than the number of boundaries, it would probably be faster to actually create a tree of the items, and insert the boundaries.



                              You could also create a list, sort it, and then look at the index. For instance, compare (sorted([(_-9.5)/10 for _ in range(20)]+[x]).index(x)-9)/10 to your function.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 7 hours ago









                              AcccumulationAcccumulation

                              1,42329




                              1,42329























                                  0














                                  Try something like this, if you don't like loops:



                                  def classify(value): 
                                  endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                  ts_folder = [ r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                  idx = [value >= end for end in endpts].index(False)
                                  if not idx:
                                  raise ValueError('Value outside of range')
                                  return ts_folder[idx-1]


                                  Of course, the loop is just "hidden" in the list comprehension.
                                  Obviously, in this example, it would be better to generate endpts and ts_fol programmatically rather than writing them all out, but you indicated that in the real situation the endpoints and values aren't so straightforward.



                                  This raises a ValueError if value ≥ 0.95 (because False is not found in the list comprehension) or if value < -0.95 (because then idx is 0); the original version raises a UnboundLocalError in these cases.



                                  You could also save three lines and skip a few comparisons by doing this:



                                  def classify(value):
                                  endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                  ts_fol = [ None, r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                  return next((ts for ts, end in zip(ts_fol, endpts) if value < end), None)


                                  This version returns None rather than raising exceptions for any value outside the bounds.






                                  share|improve this answer






























                                    0














                                    Try something like this, if you don't like loops:



                                    def classify(value): 
                                    endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                    ts_folder = [ r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                    idx = [value >= end for end in endpts].index(False)
                                    if not idx:
                                    raise ValueError('Value outside of range')
                                    return ts_folder[idx-1]


                                    Of course, the loop is just "hidden" in the list comprehension.
                                    Obviously, in this example, it would be better to generate endpts and ts_fol programmatically rather than writing them all out, but you indicated that in the real situation the endpoints and values aren't so straightforward.



                                    This raises a ValueError if value ≥ 0.95 (because False is not found in the list comprehension) or if value < -0.95 (because then idx is 0); the original version raises a UnboundLocalError in these cases.



                                    You could also save three lines and skip a few comparisons by doing this:



                                    def classify(value):
                                    endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                    ts_fol = [ None, r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                    return next((ts for ts, end in zip(ts_fol, endpts) if value < end), None)


                                    This version returns None rather than raising exceptions for any value outside the bounds.






                                    share|improve this answer




























                                      0












                                      0








                                      0







                                      Try something like this, if you don't like loops:



                                      def classify(value): 
                                      endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                      ts_folder = [ r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                      idx = [value >= end for end in endpts].index(False)
                                      if not idx:
                                      raise ValueError('Value outside of range')
                                      return ts_folder[idx-1]


                                      Of course, the loop is just "hidden" in the list comprehension.
                                      Obviously, in this example, it would be better to generate endpts and ts_fol programmatically rather than writing them all out, but you indicated that in the real situation the endpoints and values aren't so straightforward.



                                      This raises a ValueError if value ≥ 0.95 (because False is not found in the list comprehension) or if value < -0.95 (because then idx is 0); the original version raises a UnboundLocalError in these cases.



                                      You could also save three lines and skip a few comparisons by doing this:



                                      def classify(value):
                                      endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                      ts_fol = [ None, r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                      return next((ts for ts, end in zip(ts_fol, endpts) if value < end), None)


                                      This version returns None rather than raising exceptions for any value outside the bounds.






                                      share|improve this answer















                                      Try something like this, if you don't like loops:



                                      def classify(value): 
                                      endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                      ts_folder = [ r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                      idx = [value >= end for end in endpts].index(False)
                                      if not idx:
                                      raise ValueError('Value outside of range')
                                      return ts_folder[idx-1]


                                      Of course, the loop is just "hidden" in the list comprehension.
                                      Obviously, in this example, it would be better to generate endpts and ts_fol programmatically rather than writing them all out, but you indicated that in the real situation the endpoints and values aren't so straightforward.



                                      This raises a ValueError if value ≥ 0.95 (because False is not found in the list comprehension) or if value < -0.95 (because then idx is 0); the original version raises a UnboundLocalError in these cases.



                                      You could also save three lines and skip a few comparisons by doing this:



                                      def classify(value):
                                      endpts = [-0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95]
                                      ts_fol = [ None, r'-0.9', r'-0.8', r'-0.7', r'-0.6', r'-0.5', r'-0.4', r'-0.3', r'-0.2', r'-0.1', r'.0', r'.1', r'.2', r'.3', r'.4', r'.5', r'.6', r'.7', r'.8', r'.9']
                                      return next((ts for ts, end in zip(ts_fol, endpts) if value < end), None)


                                      This version returns None rather than raising exceptions for any value outside the bounds.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 1 hour ago

























                                      answered 2 hours ago









                                      KundorKundor

                                      2,9661325




                                      2,9661325






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55180829%2fpython-if-else-code-style-for-reduced-code-for-rounding-floats%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Can't compile dgruyter and caption packagesLaTeX templates/packages for writing a patent specificationLatex...

                                          Schneeberg (Smreczany) Bibliografia | Menu...

                                          Hans Bellmer Spis treści Życiorys | Upamiętnienie | Przypisy | Bibliografia | Linki zewnętrzne |...