как я могу улучшить это утверждение «если еще»?

#python #python-3.x #if-statement #conditional-statements

Вопрос:

У меня есть эта функция для определения направления луча в декартовой плоскости:

 def direction(self):
    if 180 > self.angle > 90:
        return (-1,  1)
    elif 90 > self.angle > 0:
        return ( 1,  1)
    elif 0 > self.angle > -90:
        return ( 1, -1)
    elif -90 > self.angle > -180:
        return (-1, -1)
 

Это выглядит довольно громоздко. Есть ли более простой способ сформулировать это? Это просто дает мне квадрант, в который движется луч, в зависимости от угла.

Комментарии:

1. Для справки, ваш код не возвращает None для любого угла, который является целым числом, кратным 90. Это то, чего ты хочешь?

Ответ №1:

Вам вообще не нужен условный оператор, если вы используете math.copysign и основные тригонометрические функции:

 from math import copysign, sin, cos, pi

def direction(angle):
    angle *= pi / 180
    return copysign(1, cos(angle)), copysign(1, sin(angle))
 

Если вы настаиваете на использовании условных обозначений, вы можете разделить сравнения для двух, а не для четырех случаев:

 def direction(angle):
    angle %= 360
    x = -1 if 90 < angle < 270 else  1
    y = -1 if 180 < angle else  1
    return x, y
 

На самом деле, вы можете использовать тот факт, что bool это подкласс int , чтобы удалить условные обозначения совершенно другим способом:

 def direction(angle):
    angle %= 360
    x = 1 - 2 * (90 < angle < 270)
    y = 1 - 2 * (180 < angle)
    return x, y
 

Использование циклических функций , таких как sin , cos и по модулю ( % ), улучшит обработку вашего кода.

Эти формулировки также будут лучше справляться с угловыми случаями. Ваша исходная функция вернется None под углом 90 . Этих двух версий не было бы. Вы можете настроить условия (например, заменить < на <= иногда), чтобы угловые случаи работали именно так, как вы хотите.

Комментарии:

1. да, это лаконично, но я только что понял, что утверждение if else намного быстрее, чем другие методы, которые я пробовал, включая этот

2. @pytherhub. Обновлено более простым условным

3. @pytherhub. Еще одно обновление. Нет необходимости использовать условные обозначения. Все это сводится к паре логических выражений с добавлением-умножением.

Ответ №2:

По-моему, все в порядке, вы можете заменить последний elif другим, как это

 def direction(self):
        if 180>self.angle>90:
            return (-1, 1)
        elif 90>self.angle>0:
            return (1,1)
        elif 0>self.angle>-90:
            return (1,-1)
        else:
            return (-1,-1)
 

Комментарии:

1. нет, я хотел более простой метод, потому что есть шаблон

Ответ №3:

Вы можете преобразовать угол в число квадранта (0, 1 и т.д.) и использовать его в качестве индекса в массиве:

 return [(1,1), (-1,1), (-1,-1), (1,-1)]\
       [int(self.angle % 360) // 90]
 

Это работает, даже если self.angle не является целым числом.