Python if-else code style for reduced code for rounding floats2019 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

What is the rarity of this homebrew magic staff?

Why doesn't using two cd commands in bash script execute the second command?

A sequence that has integer values for prime indexes only:

How Could an Airship Be Repaired Mid-Flight

Are there verbs that are neither telic, or atelic?

Can I use USB data pins as power source

The difference between「N分で」and「後N分で」

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

How to explain that I do not want to visit a country due to personal safety concern?

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

How to create the Curved texte?

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

Instead of Universal Basic Income, why not Universal Basic NEEDS?

Have researchers managed to "reverse time"? If so, what does that mean for physics?

Co-worker team leader wants to inject his friend's awful software into our development. What should I say to our common boss?

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

Why does Bach not break the rules here?

Brexit - No Deal Rejection

How to make healing in an exploration game interesting

Why one should not leave fingerprints on bulbs and plugs?

How could a scammer know the apps on my phone / iTunes account?

My adviser wants to be the first author

SOQL: Populate a Literal List in WHERE IN Clause

Official degrees of earth’s rotation per day



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



















  • 47





    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 鄺世銘
    13 hours ago






  • 7





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

    – chepner
    12 hours ago






  • 4





    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
    7 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



















  • 47





    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 鄺世銘
    13 hours ago






  • 7





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

    – chepner
    12 hours ago






  • 4





    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
    7 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 1 hour ago









smci

15.3k677108




15.3k677108










asked 13 hours ago









Kuang 鄺世銘Kuang 鄺世銘

826




826







  • 47





    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 鄺世銘
    13 hours ago






  • 7





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

    – chepner
    12 hours ago






  • 4





    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
    7 hours ago












  • 47





    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 鄺世銘
    13 hours ago






  • 7





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

    – chepner
    12 hours ago






  • 4





    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
    7 hours ago







47




47





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 鄺世銘
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 鄺世銘
13 hours ago




7




7





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

– chepner
12 hours ago





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

– chepner
12 hours ago




4




4





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
7 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
7 hours ago












11 Answers
11






active

oldest

votes


















26














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




















  • 1





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

    – Martin Bonner
    9 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
    9 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
    7 hours ago











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

    – Olivier Melançon
    5 hours ago











  • Assuming the intervals partition a range, binary search with the bisect module would be a good option.

    – user2357112
    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
      10 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


















    4














    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




















    • 1





      this is one of the most useful answers here

      – aaaaaa
      2 hours 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






























      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














      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


















      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














        from decimal import Decimal

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





        share|improve this answer




















        • 4





          star imports are bad practice.

          – bruno desthuilliers
          12 hours ago


















        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









          26














          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




















          • 1





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

            – Martin Bonner
            9 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
            9 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
            7 hours ago











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

            – Olivier Melançon
            5 hours ago











          • Assuming the intervals partition a range, binary search with the bisect module would be a good option.

            – user2357112
            4 hours ago















          26














          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




















          • 1





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

            – Martin Bonner
            9 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
            9 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
            7 hours ago











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

            – Olivier Melançon
            5 hours ago











          • Assuming the intervals partition a range, binary search with the bisect module would be a good option.

            – user2357112
            4 hours ago













          26












          26








          26







          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 5 hours ago

























          answered 13 hours ago









          Olivier MelançonOlivier Melançon

          13.9k22042




          13.9k22042







          • 1





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

            – Martin Bonner
            9 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
            9 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
            7 hours ago











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

            – Olivier Melançon
            5 hours ago











          • Assuming the intervals partition a range, binary search with the bisect module would be a good option.

            – user2357112
            4 hours ago












          • 1





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

            – Martin Bonner
            9 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
            9 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
            7 hours ago











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

            – Olivier Melançon
            5 hours ago











          • Assuming the intervals partition a range, binary search with the bisect module would be a good option.

            – user2357112
            4 hours ago







          1




          1





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

          – Martin Bonner
          9 hours ago





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

          – Martin Bonner
          9 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
          9 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
          9 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
          7 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
          7 hours ago













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

          – Olivier Melançon
          5 hours ago





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

          – Olivier Melançon
          5 hours ago













          Assuming the intervals partition a range, binary search with the bisect module would be a good option.

          – user2357112
          4 hours ago





          Assuming the intervals partition a range, binary search with the bisect module would be a good option.

          – user2357112
          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 7 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
                    10 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
                    10 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
                    10 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
                    10 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
                  10 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
                  10 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

                  904216




                  904216












                  • 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











                  4














                  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




















                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    2 hours ago















                  4














                  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




















                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    2 hours ago













                  4












                  4








                  4







                  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 7 hours ago









                  Eric Towers

                  3,6191015




                  3,6191015










                  answered 9 hours ago









                  Martin BonnerMartin Bonner

                  23.6k33266




                  23.6k33266







                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    2 hours ago












                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    2 hours ago







                  1




                  1





                  this is one of the most useful answers here

                  – aaaaaa
                  2 hours ago





                  this is one of the most useful answers here

                  – aaaaaa
                  2 hours 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 13 hours ago









                      JerilJeril

                      2,4411735




                      2,4411735





















                          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 12 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














                          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














                          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












                          1








                          1







                          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 5 hours ago









                          Olivier Melançon

                          13.9k22042




                          13.9k22042










                          answered 13 hours ago









                          MelKoutchMelKoutch

                          555




                          555







                          • 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











                          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 8 hours ago









                              AcccumulationAcccumulation

                              1,42329




                              1,42329





















                                  0














                                  from decimal import Decimal

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





                                  share|improve this answer




















                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago















                                  0














                                  from decimal import Decimal

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





                                  share|improve this answer




















                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago













                                  0












                                  0








                                  0







                                  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 13 hours ago









                                  Asif AkhtarAsif Akhtar

                                  76110




                                  76110







                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago












                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago







                                  4




                                  4





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  12 hours ago





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  12 hours ago











                                  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 2 hours ago

























                                      answered 3 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

                                          Are there any AGPL-style licences that require source code modifications to be public? Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Force derivative works to be publicAre there any GPL like licenses for Apple App Store?Do you violate the GPL if you provide source code that cannot be compiled?GPL - is it distribution to use libraries in an appliance loaned to customers?Distributing App for free which uses GPL'ed codeModifications of server software under GPL, with web/CLI interfaceDoes using an AGPLv3-licensed library prevent me from dual-licensing my own source code?Can I publish only select code under GPLv3 from a private project?Is there published precedent regarding the scope of covered work that uses AGPL software?If MIT licensed code links to GPL licensed code what should be the license of the resulting binary program?If I use a public API endpoint that has its source code licensed under AGPL in my app, do I need to disclose my source?

                                          2013 GY136 Descoberta | Órbita | Referências Menu de navegação«List Of Centaurs and Scattered-Disk Objects»«List of Known Trans-Neptunian Objects»

                                          Button changing it's text & action. Good or terrible? The 2019 Stack Overflow Developer Survey Results Are Inchanging text on user mouseoverShould certain functions be “hard to find” for powerusers to discover?Custom liking function - do I need user login?Using different checkbox style for different checkbox behaviorBest Practices: Save and Exit in Software UIInteraction with remote validated formMore efficient UI to progress the user through a complicated process?Designing a popup notice for a gameShould bulk-editing functions be hidden until a table row is selected, or is there a better solution?Is it bad practice to disable (replace) the context menu?