On Thu, Oct 23, 2014 at 5:27 AM, Matthew Ruffalo <mm...@case.edu> wrote: > On 10/22/2014 12:40 PM, Chris Angelico wrote: >> That's true when it's fundamentally arithmetic. But part of that >> readability difference is the redundancy in the second one. What if it >> weren't so redundant? >> >> 'Negative' if x < 0 else 'Low' if x < 10 else 'Mid' if x < 20 else 'High' >> >> You can't easily turn that into a dict lookup, nor indexing. It's >> either a chained if/elif tree or nested if/else expressions, which >> come to the same thing. > No, you can't turn that into a dict lookup, but this is one of the > canonical use cases for the bisect module: > >>>> from bisect import bisect >>>> breakpoints = [0, 10, 20] >>>> labels = ['Negative', 'Low', 'Mid', 'High'] >>>> values = [-5, 5, 15, 25] >>>> [labels[bisect(breakpoints, value)] for value in values] > ['Negative', 'Low', 'Mid', 'High'] > > It's also worth noting that using bisect is O(log(n)) instead of O(n), > but if you're going to hit a point where the asymptotic behavior matters > I'm sure you will have long since abandoned a manually-written if/elif > chain.
Indeed. If the performance is making any difference, something's gone wrong. I'm seeing that as not significantly clearer than the chained if/else statement or expression: you need a list of breakpoints and a list of results, which need to be kept in sync. But there's probably no ideal solution to this. ChrisA -- https://mail.python.org/mailman/listinfo/python-list