Python - Ensuring a variable holds a positive number

此生再无相见时 提交于 2019-12-04 14:00:08

问题


I am looking for an elegant way to ensure that a given variable remains positive.

I have two variables that hold positive float numbers and I decrement them according to certain conditions. At the end I want to guarantee that I still have positive numbers (or 0 at most). The pseudo code looks something like this:

list = [...]

value1 = N
value2 = M

for element in list:
    if ... :
        value1 -= X
    if ... :
        value2 -= Y

Is there a more elegant solution than just adding two ifs at the end?


回答1:


I am unclear as to what you want to do -- either the variables can be negative, or they can't.

  • If you are decrementing a variable repeatedly and after doing so you want to check whether they are negative, do so with an if -- that's what it's for!

    if value < 0: # do stuff
    
  • If you think the variables should never be negative and you want to assert this fact in the code in the code, you do

    assert value > 0
    

    which may raise an AssertionError if the condition doesn't hold (assert will not execute when Python is not run in debug mode).

  • If you want the variable to be 0 if it has been decreased below 0, do

    value = max(value, 0)
    
  • If you want the variable to be negated if it is negative, do

    value = value if value > 0 else -value
    

    or

    value = abs(value)
    



回答2:


Use value1 = max(0, value1) and the same for value2 at the end of the iteration.




回答3:


For floats, I like the max(0, value) already given by Constantinius. You can even combine it with the decrement and use tuple unpacking to handle both values at once:

value1, value2 = max(0, value1-1), max(0, value2-1)

Some tricks for integers only (for the record, since I already posted them without realizing you were dealing with floats):

When decrementing you can use this:

value -= value and 1

Assuming the value always starts out >= 0, this won't let it get below 0.

When the value is zero, this evaluates to value -= 0. When value is not zero, it evaluates to value -= 1.

You could also use the ternary operator, which is more readable:

value -= 1 if value > 0 else 0



回答4:


Here's another take on it: a class which acts as a soft limit to the numbers value:

The numbers will never be in an invalid state:

SoftPositiveNumber(5) - 20 == 0 evaluates to true

from functools import total_ordering

@total_ordering
class SoftPositiveNumber(object):
    """This class acts like a number but will not allow
    the contained value to be less than zero"""
    def __init__(self, value):
        if isinstance(value, SoftPositiveNumber):
            value = value.value
        self.value = value
        if self.value < 0:
            self.value = 0
    def __str__(self):
        return str(self.value)
    def __int__(self):
        return int(self.value)
    def __float__(self):
        return float(self.value)
    def __repr__(self):
        return f"SoftPositiveNumber({self.value})"
    def __eq__(self, other):
        if isinstance(other, SoftPositiveNumber):
            return self.value == other.value
        return self.value == other
    def __lt__(self, other):
        if isinstance(other, SoftPositiveNumber):
            return self.value < other.value
        return self.value < other
    def __iadd__(self, other):
        if isinstance(other, SoftPositiveNumber):
            self.value += other.value
        else:
            self.value += other
        if self.value < 0:
            self.value = 0
        return self
    def __isub__(self, other):
        if isinstance(other, SoftPositiveNumber):
            self.value -= other.value
        else:
            self.value -= other
        if self.value < 0:
            self.value = 0
        return self
    def __add__(self, other):
        if isinstance(other, SoftPositiveNumber):
            return SoftPositiveNumber(self.value + other.value)
        return SoftPositiveNumber(self.value + other)
    def __sub__(self, other):
        if isinstance(other, SoftPositiveNumber):
            return SoftPositiveNumber(self.value - other.value)
        return SoftPositiveNumber(self.value - other)
    __rsub__ = __sub__
    __radd__ = __add__


来源:https://stackoverflow.com/questions/7122535/python-ensuring-a-variable-holds-a-positive-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!