How can I shortern if, elif, elif statements in Python

Question:

How can I make the following code short:

q=0.34
density=''
    if abs(q) ==0:
        density='Null'
    elif abs(q) <= 0.09:
        density='negligible'
    elif abs(q) <= 0.49:
        density='slight'
    elif abs(q) <= 0.69:
        density='strong'
    else:
        density='very strong'
    print(q,", ", density)

Expected output :

0.34, 'slight'

I think there is a solution by using dictionaries,

Any help from your side will be highly appreciated !

Asked By: Khaled DELLAL

||

Answers:

You can try something like that:

def f(q):
    # List of your limits values and their density values
    values = [(0, "Null"), (0.09, "negligible"), (0.49, "slight"), (0.69, "strong")]
    # Default value of the density, i.e. your else statement
    density = "very strong"

    # Search the good density and stop when it is found
    for (l, d) in values:
        if abs(q) <= l:
            density = d
            break

    print(q, ", ", density)

I think the comments are explicit enough to explain the code but don’t hesitate to ask if it is not clear.

Answered By: Raida

Coded up a solution here which instead of checking all the if-else statements, it rather loops through an array of values and finds in which space the input value belongs:

import numpy as np
vals = [0, 0.09,0.49,0.69,]
msgs = ['Null', 'negligible', 'slight', 'strong', 'very strong']

q=0.5
density=''

def calc_density(q:float) -> str:
    are_greater_than = q>np.array(vals)
    if all(are_greater_than): bools = -1
    else: bools = np.argmin(are_greater_than)
    return msgs[bools]

for q in [-0.1, 0.0, 0.2, 0.07, 0.8]:
    print(q, calc_density(q))

# >>> -0.1 Null
# >>> 0.0 Null
# >>> 0.2 slight
# >>> 0.07 negligible
# >>> 0.8 very strong

Hope this helps!

If this is used in a single place, this code is good as is, and there is nothing wrong with it.

If there are more places in which you want to assign a numeric range to a string, you can use a function or a class to do it,in a way that you can encode the values in a better way.

For example,a simple, configurable function to do the same would be:

def _range_to_str(ranges, value):
    for threshold, description in ranges.items():
         if value <= threshold:
              return description
    raise ValueError(f"{value} out of range for {ranges}")

densities = {0: "", 0.09:"negligible", 0.49: "slight", ...}

def density_description(value):
    return _range_to_str(densities, value)
Answered By: jsbueno
q=0.34
density=''
conditions = [
(0,'null'),
(0.09, 'negligible'),
(0.49, 'slight'),
(0.69, 'strong')
]
# loops through the conditions and check if they are smaller
# if they are, immediately exit the loop, retaining the correct density value
for limit, density in conditions:
    if q <= limit:
        break
# this if statement checks if its larger than the last condition
# this ensures that even if it never reached any condition, it doesn't
# just output the last value
if q > conditions[-1][0]:
    density = 'very strong'

print(q,", ", density)

of course if you want to make it more short 🙂
(assuming q is always smaller than 9999)

q=0.34
c = [(0,'null'),(0.09,'negligible'),(0.49,'slight'),(0.69,'strong'), (9999,'very strong')]
print(q,',',[j for i,j in c if abs(q)<=i][0])

EDIT: fixed mistake in answer noted by Khaled DELLAL

Answered By: eroc1234
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.