Python - обеспечение переменной содержит положительное число - PullRequest
3 голосов
/ 19 августа 2011

Я ищу элегантный способ гарантировать, что данная переменная остается положительной.

У меня есть две переменные, которые содержат положительные числа с плавающей точкой, и я уменьшаю их в соответствии с определенными условиями. В конце я хочу гарантировать, что у меня все еще есть положительные числа (или не более 0). Псевдокод выглядит примерно так:

list = [...]

value1 = N
value2 = M

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

Есть ли более элегантное решение, чем просто добавление двух ifs в конце?

Ответы [ 4 ]

23 голосов
/ 19 августа 2011

Мне неясно, что вы хотите сделать - либо переменные могут быть отрицательными, либо они не могут.

  • Если вы уменьшаете переменную многократно и после выполнениятак что вы хотите проверить, являются ли они отрицательными, сделайте это с if - вот для чего!

    if value < 0: # do stuff
    
  • Если вы думаете, что переменные должны никогда не будьте отрицательными, и вы хотите утвердить этот факт в коде в коде, вы выполняете

    assert value > 0
    

    , что может вызвать AssertionError, если условие не выполняется (assert не будет выполнятьсякогда Python не запущен в режиме отладки).

  • Если вы хотите, чтобы переменная была 0, если она была уменьшена ниже 0, выполните

    value = max(value, 0)
    
  • Если вы хотите, чтобы переменная была отрицательной, если она отрицательная, выполните

    value = value if value > 0 else -value
    

    или

    value = abs(value)
    
7 голосов
/ 19 августа 2011

Используйте value1 = max(0, value1) и то же самое для value2 в конце итерации.

4 голосов
/ 19 августа 2011

Для поплавков мне нравится max(0, value), уже предоставленный Константином. Вы даже можете комбинировать его с декрементом и использовать распаковку кортежей для обработки обоих значений одновременно:

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

Некоторые трюки только для целых чисел (для записи, так как я уже разместил их, даже не подозревая, что вы имели дело с числами):

При уменьшении вы можете использовать это:

value -= value and 1

Предполагая, что значение всегда начинается с> = 0, это не позволит ему опуститься ниже 0.

Когда значение равно нулю, это оценивается как value -= 0. Когда значение не равно нулю, оно оценивается как value -= 1.

Вы также можете использовать троичный оператор, который более читабелен:

value -= 1 if value > 0 else 0
0 голосов
/ 02 марта 2018

Вот еще один пример: класс, который действует как мягкое ограничение значения чисел:

Числа никогда не будут в недопустимом состоянии:

SoftPositiveNumber(5) - 20 == 0 оценивается как истинное

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__
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...