HTF
HTF

Reputation: 7270

Python: conditional unpacking and assignment

I would like to get a percentage from initial values based on results, but only for result greater than 100, otherwise return initial value. At the moment there is a check for both results if all(results) >= 100 and if I add a filter to generator expression (i*percent/100 for i in results if i >= 100), variable assignment will fail. In summary, it should skip calculation if result is less than 100 but run otherwise, so if results are (500, 0) function should return (250, 75). What would be the pythonic way to do this?

total = 150
user_total = 75

def test01(results=(500, 0)):
    if all(results) >= 100:
        percent = 50
        total, user_total = (i*percent/100 for i in results)
    return (total, user_total)

Upvotes: 1

Views: 1583

Answers (1)

Eugene Yarmash
Eugene Yarmash

Reputation: 149823

The all() function returns a Boolean value, so all(results) >= 100 doesn't do what you want. As bool is a subclass of int in Python, the comparison won't raise an exception in either Python 2 or Python 3.

The proper way would be to use a generator expression as an argument to all(). Also, you could make total and user_total keyword arguments if they're only used in the function:

def test01(results=(500, 0), total=150, user_total=75):
    if all(x >= 100 for x in results):
        percent = 50
        total, user_total = (i*percent/100 for i in results)
    return total, user_total

Update: if you want to skip calculation if a result is less than 100, you could use a generator with a ternary operator:

def test01(results=(500, 0), defaults=(150, 75)):
    percent = 50
    total, user_total = (results[i]*percent/100 if results[i] >= 100 
                         else defaults[i] for i in [0, 1])

Or with zip():

def test01(results=(500, 0), defaults=(150, 75)):
    percent = 50
    total, user_total = (r*percent/100 if r >= 100 else d
                         for r, d in zip(results, defaults))

Upvotes: 4

Related Questions