Подтвердить что ты не робот

Есть ли способ написать эти ifs лучше?

Мне нужно записать эти четыре if в Python. Обратите внимание, что он делает, меняется между четырьмя возможными состояниями в цикле: 1,0 -> 0,1 -> -1,0 -> 0,-1 и назад к первому.

if [dx, dy] == [1,0]:
    dx, dy = 0, 1
if [dx, dy] == 0, 1:
    dx, dy = -1, 0
if [dx, dy] == [-1, 0]
    dx, dy = 0, -1
if [dx, dy] == [0, -1]:
    dx, dy = 1, 0

Может ли кто-нибудь предложить мне лучший/лучший способ написать это?

4b9b3361

Ответ 1

dx, dy = -dy, dx

В случае сомнений примените математику.;)

Ответ 2

Предложение Магнуса, несомненно, правильный ответ на ваш вопрос, поставленный, но вообще говоря, вы хотите использовать словарь для таких проблем, как это:

statemap = {(1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0)}

dx, dy = statemap[dx, dy]

Даже в этом случае я мог бы лучше использовать словарь, так как ясно, что существует ровно четыре состояния и они повторяются, но трудно противостоять чистой красоте всех математик.

Кстати, у кода в вашем вопросе есть ошибка, и, считая, что значения, которые вы тестируете, являются единственными возможными значениями, эквивалентны:

dx, dy = 1, 0

Ошибка в том, что вам нужно elif для второго и последующих условий, иначе вы продолжите тестирование dx и dy после их изменения. Если они 1 и 0, тогда все ваши условия будут истинными, и в конце концов они останутся одинаковыми! Если они начинаются как 0 и 1, тогда второе и все последующие условия будут истинными, и вы снова получите 1, 0. И так далее...

Ответ 3

Просто протягивая Магнуса ответ. Если вы представляете [dx, dy] в качестве вектора, то, что вы на самом деле делаете, это rotation 90 градусов (или PI/2).

Чтобы вычислить это, вы можете использовать следующее преобразование:

two dimensional rotation

Что в вашем случае перевести на:

x = x * cos(90) - y * sin(90)
y = x * sin(90) + y * cos(90)

Так как sin(90) = 1 и cos(90) = 0, мы упрощаем его:

x, y = -y, x

И вот он у вас есть!

Ответ 4

Значения, с которыми вы работаете, выглядят как единичный вектор, который непрерывно вращается - другими словами, phasor. Сложные числа - это координаты, поэтому:

# at initialization
phase = 1
# at the point of modification
phase *= 1j
dx, dy = phase.real, phase.imag

Предполагая, что моя интерпретация значения значений dx, dy верна, это дает вам дополнительную гибкость в случае, если впоследствии окажется, что вы хотите повернуть на какую-то другую сумму на каждом шаге.

Ответ 5

Хотя я бы пошел с ответом Магнуса, вот еще один подход к вращению над набором значений:

def rotate(*states):
    while 1:
        for state in states:
            yield state

for dx, dy in rotate((1, 0), (0, 1), (-1, 0), (0, -1)):
    pass

Обратите внимание, что в цикле for dx, dy должен быть break, иначе он никогда не закончится.