#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
не является целым числом.