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












15















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



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

return ts_folder









share|improve this question




















  • 48





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

    – Aran-Fey
    14 hours ago











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

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






  • 4





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

    – Eric Duminil
    7 hours ago
















15















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



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

return ts_folder









share|improve this question




















  • 48





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

    – Aran-Fey
    14 hours ago











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

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






  • 4





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

    – Eric Duminil
    7 hours ago














15












15








15


3






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



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

return ts_folder









share|improve this question
















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



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

return ts_folder






python floating-point rounding number-formatting






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 hours ago









smci

15.3k677108




15.3k677108










asked 14 hours ago









Kuang 鄺世銘Kuang 鄺世銘

826




826








  • 48





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

    – Aran-Fey
    14 hours ago











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

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






  • 4





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

    – Eric Duminil
    7 hours ago














  • 48





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

    – Aran-Fey
    14 hours ago











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

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






  • 4





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

    – Eric Duminil
    7 hours ago








48




48





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

– Aran-Fey
14 hours ago





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

– Aran-Fey
14 hours ago













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

– connectyourcharger
14 hours ago





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

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





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

– chepner
13 hours ago




4




4





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

– Eric Duminil
7 hours ago





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

– Eric Duminil
7 hours ago












11 Answers
11






active

oldest

votes


















26














Specific solution



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



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


General solution



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



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

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

value = -0.73

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


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






share|improve this answer





















  • 1





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

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






  • 1





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

    – Eric Duminil
    7 hours ago











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

    – Olivier Melançon
    6 hours ago











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

    – user2357112
    5 hours ago



















11














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




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




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


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



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


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






share|improve this answer































    7














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



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

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


    Output:



    >>> classify(-0.78)
    -0.8





    share|improve this answer





















    • 15





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

      – bruno desthuilliers
      12 hours ago






    • 1





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

      – Arthur Tacca
      10 hours ago



















    5














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



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


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



    More on round()






    share|improve this answer


























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

      – Eric Duminil
      7 hours ago













    • Oh my bad, should be good now

      – Fukiyel
      7 hours ago



















    4














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



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


    write



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


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



        elif -0.85 <= value < -0.75:


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



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


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






    share|improve this answer





















    • 1





      this is one of the most useful answers here

      – aaaaaa
      3 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
        7 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
        14 hours ago



















      0














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



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



      Doing a binary search explicitly would be something like this:



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


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



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



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






      share|improve this answer































        0














        from decimal import Decimal

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





        share|improve this answer





















        • 4





          star imports are bad practice.

          – bruno desthuilliers
          12 hours ago



















        0














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



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


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



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



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



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


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






        share|improve this answer

























          Your Answer






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

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

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

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


          }
          });














          draft saved

          draft discarded


















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

          Post as a guest















          Required, but never shown

























          11 Answers
          11






          active

          oldest

          votes








          11 Answers
          11






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          26














          Specific solution



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



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


          General solution



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



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

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

          value = -0.73

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


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






          share|improve this answer





















          • 1





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

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






          • 1





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

            – Eric Duminil
            7 hours ago











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

            – Olivier Melançon
            6 hours ago











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

            – user2357112
            5 hours ago
















          26














          Specific solution



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



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


          General solution



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



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

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

          value = -0.73

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


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






          share|improve this answer





















          • 1





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

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






          • 1





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

            – Eric Duminil
            7 hours ago











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

            – Olivier Melançon
            6 hours ago











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

            – user2357112
            5 hours ago














          26












          26








          26







          Specific solution



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



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


          General solution



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



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

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

          value = -0.73

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


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






          share|improve this answer















          Specific solution



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



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


          General solution



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



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

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

          value = -0.73

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


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







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 5 hours ago

























          answered 14 hours ago









          Olivier MelançonOlivier Melançon

          13.9k22042




          13.9k22042








          • 1





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

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






          • 1





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

            – Eric Duminil
            7 hours ago











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

            – Olivier Melançon
            6 hours ago











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

            – user2357112
            5 hours ago














          • 1





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

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






          • 1





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

            – Eric Duminil
            7 hours ago











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

            – Olivier Melançon
            6 hours ago











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

            – user2357112
            5 hours ago








          1




          1





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

          – Martin Bonner
          10 hours ago





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

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




          1




          1





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

          – Eric Duminil
          7 hours ago





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

          – Eric Duminil
          7 hours ago













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

          – Olivier Melançon
          6 hours ago





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

          – Olivier Melançon
          6 hours ago













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

          – user2357112
          5 hours ago





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

          – user2357112
          5 hours ago













          11














          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




























            11














            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


























              11












              11








              11







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









              PeterPeter

              11.5k1846




              11.5k1846























                  7














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



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

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


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer





















                  • 15





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

                    – bruno desthuilliers
                    12 hours ago






                  • 1





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

                    – Arthur Tacca
                    10 hours ago
















                  7














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



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

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


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer





















                  • 15





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

                    – bruno desthuilliers
                    12 hours ago






                  • 1





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

                    – Arthur Tacca
                    10 hours ago














                  7












                  7








                  7







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



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

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


                  Output:



                  >>> classify(-0.78)
                  -0.8





                  share|improve this answer















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



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

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


                  Output:



                  >>> classify(-0.78)
                  -0.8






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 10 hours ago









                  chepner

                  257k34247339




                  257k34247339










                  answered 13 hours ago









                  Hirabayashi TaroHirabayashi Taro

                  533311




                  533311








                  • 15





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

                    – bruno desthuilliers
                    12 hours ago






                  • 1





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

                    – Arthur Tacca
                    10 hours ago














                  • 15





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

                    – bruno desthuilliers
                    12 hours ago






                  • 1





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

                    – Arthur Tacca
                    10 hours ago








                  15




                  15





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

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




                  1




                  1





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

                  – Arthur Tacca
                  10 hours ago





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

                  – Arthur Tacca
                  10 hours ago











                  5














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



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


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



                  More on round()






                  share|improve this answer


























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

                    – Eric Duminil
                    7 hours ago













                  • Oh my bad, should be good now

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













                  • Oh my bad, should be good now

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

























                  answered 14 hours ago









                  FukiyelFukiyel

                  904216




                  904216













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

                    – Eric Duminil
                    7 hours ago













                  • Oh my bad, should be good now

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













                  • Oh my bad, should be good now

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















                  Oh my bad, should be good now

                  – Fukiyel
                  7 hours ago





                  Oh my bad, should be good now

                  – Fukiyel
                  7 hours ago











                  4














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



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


                  write



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


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



                      elif -0.85 <= value < -0.75:


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



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


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






                  share|improve this answer





















                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    3 hours ago
















                  4














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



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


                  write



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


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



                      elif -0.85 <= value < -0.75:


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



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


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






                  share|improve this answer





















                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    3 hours ago














                  4












                  4








                  4







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



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


                  write



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


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



                      elif -0.85 <= value < -0.75:


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



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


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






                  share|improve this answer















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



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


                  write



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


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



                      elif -0.85 <= value < -0.75:


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



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


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







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 8 hours ago









                  Eric Towers

                  3,6191015




                  3,6191015










                  answered 10 hours ago









                  Martin BonnerMartin Bonner

                  23.6k33266




                  23.6k33266








                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    3 hours ago














                  • 1





                    this is one of the most useful answers here

                    – aaaaaa
                    3 hours ago








                  1




                  1





                  this is one of the most useful answers here

                  – aaaaaa
                  3 hours ago





                  this is one of the most useful answers here

                  – aaaaaa
                  3 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 14 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
                            7 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
                            7 hours ago














                          1












                          1








                          1







                          How about turning it into a loop?



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


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






                          share|improve this answer













                          How about turning it into a loop?



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


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







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 12 hours ago









                          MehrdadMehrdad

                          129k90415758




                          129k90415758













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

                            – Eric Duminil
                            7 hours ago



















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

                            – Eric Duminil
                            7 hours ago

















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

                          – Eric Duminil
                          7 hours ago





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

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














                          1












                          1








                          1







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



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



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


                          That code will print 5.77






                          share|improve this answer















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



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



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


                          That code will print 5.77







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 5 hours ago









                          Olivier Melançon

                          13.9k22042




                          13.9k22042










                          answered 14 hours ago









                          MelKoutchMelKoutch

                          555




                          555








                          • 2





                            Please try and answer with a clear example

                            – AJS
                            14 hours ago














                          • 2





                            Please try and answer with a clear example

                            – AJS
                            14 hours ago








                          2




                          2





                          Please try and answer with a clear example

                          – AJS
                          14 hours ago





                          Please try and answer with a clear example

                          – AJS
                          14 hours ago











                          0














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



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



                          Doing a binary search explicitly would be something like this:



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


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



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



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






                          share|improve this answer




























                            0














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



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



                            Doing a binary search explicitly would be something like this:



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


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



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



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






                            share|improve this answer


























                              0












                              0








                              0







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



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



                              Doing a binary search explicitly would be something like this:



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


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



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



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






                              share|improve this answer













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



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



                              Doing a binary search explicitly would be something like this:



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


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



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



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







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 8 hours ago









                              AcccumulationAcccumulation

                              1,42329




                              1,42329























                                  0














                                  from decimal import Decimal

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





                                  share|improve this answer





















                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago
















                                  0














                                  from decimal import Decimal

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





                                  share|improve this answer





















                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago














                                  0












                                  0








                                  0







                                  from decimal import Decimal

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





                                  share|improve this answer















                                  from decimal import Decimal

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






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited 6 hours ago









                                  wizzwizz4

                                  3,60011637




                                  3,60011637










                                  answered 14 hours ago









                                  Asif AkhtarAsif Akhtar

                                  76110




                                  76110








                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago














                                  • 4





                                    star imports are bad practice.

                                    – bruno desthuilliers
                                    12 hours ago








                                  4




                                  4





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  12 hours ago





                                  star imports are bad practice.

                                  – bruno desthuilliers
                                  12 hours ago











                                  0














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



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


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



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



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



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


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






                                  share|improve this answer






























                                    0














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



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


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



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



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



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


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






                                    share|improve this answer




























                                      0












                                      0








                                      0







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



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


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



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



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



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


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






                                      share|improve this answer















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



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


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



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



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



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


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







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 3 hours ago

























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

                                          Contact image not getting when fetch all contact list from iPhone by CNContact

                                          count number of partitions of a set with n elements into k subsets

                                          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks