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












16















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




















  • 49





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

    – Aran-Fey
    16 hours ago











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

    – connectyourcharger
    16 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 鄺世銘
    16 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
    15 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
    9 hours ago
















16















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




















  • 49





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

    – Aran-Fey
    16 hours ago











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

    – connectyourcharger
    16 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 鄺世銘
    16 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
    15 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
    9 hours ago














16












16








16


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









smci

15.3k677108




15.3k677108










asked 16 hours ago









Kuang 鄺世銘Kuang 鄺世銘

876




876








  • 49





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

    – Aran-Fey
    16 hours ago











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

    – connectyourcharger
    16 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 鄺世銘
    16 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
    15 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
    9 hours ago














  • 49





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

    – Aran-Fey
    16 hours ago











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

    – connectyourcharger
    16 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 鄺世銘
    16 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
    15 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
    9 hours ago








49




49





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

– Aran-Fey
16 hours ago





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

– Aran-Fey
16 hours ago













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

– connectyourcharger
16 hours ago





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

– connectyourcharger
16 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 鄺世銘
16 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 鄺世銘
16 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
15 hours ago





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

– chepner
15 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
9 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
9 hours ago












11 Answers
11






active

oldest

votes


















27














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











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

    – Olivier Melançon
    8 hours ago






  • 1





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

    – user2357112
    7 hours ago



















13














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





















    • 16





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



















    5














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













    • Oh my bad, should be good now

      – Fukiyel
      9 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
        9 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
        16 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





















        • 5





          star imports are bad practice.

          – bruno desthuilliers
          14 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









          27














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











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

            – Olivier Melançon
            8 hours ago






          • 1





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

            – user2357112
            7 hours ago
















          27














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











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

            – Olivier Melançon
            8 hours ago






          • 1





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

            – user2357112
            7 hours ago














          27












          27








          27







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

























          answered 16 hours ago









          Olivier MelançonOlivier Melançon

          13.9k22042




          13.9k22042








          • 1





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

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











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

            – Olivier Melançon
            8 hours ago






          • 1





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

            – user2357112
            7 hours ago














          • 1





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

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











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

            – Olivier Melançon
            8 hours ago






          • 1





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

            – user2357112
            7 hours ago








          1




          1





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

          – Martin Bonner
          11 hours ago





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

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













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

          – Olivier Melançon
          8 hours ago





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

          – Olivier Melançon
          8 hours ago




          1




          1





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

          – user2357112
          7 hours ago





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

          – user2357112
          7 hours ago













          13














          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




























            13














            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


























              13












              13








              13







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









              PeterPeter

              11.6k1846




              11.6k1846























                  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





















                  • 16





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





















                  • 16





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









                  chepner

                  257k34247339




                  257k34247339










                  answered 15 hours ago









                  Hirabayashi TaroHirabayashi Taro

                  533311




                  533311








                  • 16





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














                  • 16





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








                  16




                  16





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











                  5














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
















                  5














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














                  5












                  5








                  5







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









                  Eric Towers

                  3,6191015




                  3,6191015










                  answered 11 hours ago









                  Martin BonnerMartin Bonner

                  23.6k33266




                  23.6k33266








                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    4 hours ago














                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    4 hours ago








                  1




                  1





                  this is one of the most useful answers here

                  – aaaaaa
                  4 hours ago





                  this is one of the most useful answers here

                  – aaaaaa
                  4 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
                    9 hours ago













                  • Oh my bad, should be good now

                    – Fukiyel
                    9 hours ago
















                  5














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



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


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



                  More on round()






                  share|improve this answer


























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

                    – Eric Duminil
                    9 hours ago













                  • Oh my bad, should be good now

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

























                  answered 16 hours ago









                  FukiyelFukiyel

                  906216




                  906216













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













                  • Oh my bad, should be good now

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













                  • Oh my bad, should be good now

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















                  Oh my bad, should be good now

                  – Fukiyel
                  9 hours ago





                  Oh my bad, should be good now

                  – Fukiyel
                  9 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 16 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
                            9 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
                            9 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 14 hours ago









                          MehrdadMehrdad

                          129k90415758




                          129k90415758













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

                            – Eric Duminil
                            9 hours ago



















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

                            – Eric Duminil
                            9 hours ago

















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

                          – Eric Duminil
                          9 hours ago





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

                          – Eric Duminil
                          9 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
                            16 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
                            16 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 7 hours ago









                          Olivier Melançon

                          13.9k22042




                          13.9k22042










                          answered 16 hours ago









                          MelKoutchMelKoutch

                          555




                          555








                          • 2





                            Please try and answer with a clear example

                            – AJS
                            16 hours ago














                          • 2





                            Please try and answer with a clear example

                            – AJS
                            16 hours ago








                          2




                          2





                          Please try and answer with a clear example

                          – AJS
                          16 hours ago





                          Please try and answer with a clear example

                          – AJS
                          16 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 10 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





















                                  • 5





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    14 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





















                                  • 5





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    14 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 8 hours ago









                                  wizzwizz4

                                  3,60011637




                                  3,60011637










                                  answered 16 hours ago









                                  Asif AkhtarAsif Akhtar

                                  76110




                                  76110








                                  • 5





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    14 hours ago














                                  • 5





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    14 hours ago








                                  5




                                  5





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  14 hours ago





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  14 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 5 hours ago

























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

                                          Loup dans la culture

                                          How to solve the problem of ntp “Unable to contact time server” from KDE?

                                          ASUS Zenbook UX433/UX333 — Configure Touchpad-embedded numpad on Linux