Yashoda Neupane - 4 months ago 6

Python Question

I want to select elements from list of numbers within lower and upper bounds, each of which is optional. I can write it as a series of if and else for all possible cases. Can we reduce these branching and write in a concise way?

`def select_within_bounds(li, lower=None, upper=None):`

if lower is None:

if upper is None:

return li

else:

return [v for v in li if v <= upper]

else:

if upper is None:

return [v for v in li if v >= lower]

else:

return [v for v in li if lower <= v <= upper]

#example:

my_list = [1, 4, 5, 3, 6, 9]

print(select_within_bounds(my_list))

print(select_within_bounds(my_list, 3, 8))

print(select_within_bounds(my_list, lower=3))

print(select_within_bounds(my_list, upper=8))

print(select_within_bounds(my_list, lower=3,upper=8))

#results in

[1, 4, 5, 3, 6, 9]

[4, 5, 3, 6]

[4, 5, 3, 6, 9]

[1, 4, 5, 3, 6]

[4, 5, 3, 6]

Answer

You know the answer when the numeric bounds are always present. So, you can first derive the bounds and then apply the same logic. That is:

```
def select_within_bounds(li, lower=None, upper=None):
lower, upper = min(li) if lower is None else lower, upper or max(li)
return [v for v in li if lower <= v <= upper]
```

**Updated:** based on @Copperfield's comment:
we can avoid calumniating min/max by using default boundaries as symbolic infinities (linear vs constant cost)

```
lower, upper = float("-inf") if lower is None else lower, upper or float("inf")
```

Source (Stackoverflow)

Comments