with simple loop for examples python control-structure

for - simple loop python



¿Hay una manera de escribir estos ifs mejor? (5)

Necesito escribir estos cuatro if s en Python. Observe lo que hace, está cambiando entre cuatro estados posibles en un bucle: 1,0 -> 0,1 -> -1,0 -> 0,-1 y de vuelta al primero.

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

¿Alguien puede sugerirme una forma mejor / mejor de escribir esto?


La sugerencia de Magnus es, sin lugar a dudas, la respuesta correcta a su pregunta tal como se plantea, pero, en general, desea utilizar un diccionario para problemas como este:

statemap = {(1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0)} dx, dy = statemap[dx, dy]

Incluso en este caso, podría argumentar que usar un diccionario es mejor, ya que está claro que hay exactamente cuatro estados y que se repiten, pero es difícil resistirse a la belleza de todas las matemáticas.

Por cierto, el código en su pregunta tiene un error, y, asumiendo que los valores que usted prueba son los únicos valores posibles, es equivalente a:

dx, dy = 1, 0

El error es que necesitas elif para la segunda y las siguientes condiciones, de lo contrario continuarás probando dx y dy después de cambiarlos. ¡Si son 1 y 0 , entonces todas tus condiciones serán verdaderas y terminarán igual al final! Si comienzan como 0 y 1 , la segunda y todas las condiciones subsiguientes serán verdaderas, y nuevamente terminará con 1, 0 . Y así...


Los valores con los que está trabajando parecen ser un vector unitario que rota continuamente; en otras palabras, un phasor . Los números complejos son coordenadas , por lo que:

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

Suponiendo que mi interpretación del significado de los valores de dx, dy es correcta, esto le brinda mayor flexibilidad en caso de que más adelante desee rotar en otra cantidad en cada paso.


Si bien aceptaría la respuesta de Magnus, aquí hay otro enfoque para rotar sobre un conjunto de valores:

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

Tenga en cuenta que debería haber una break en algún lugar del bucle for dx, dy contrario nunca terminará.


Solo extendiendo la respuesta de Magnus. Si imaginas [dx, dy] como un vector, lo que realmente estás haciendo es una rotation de 90 grados (o PI / 2).

Para calcular esto, puedes usar la siguiente transformación:

Que en su caso se traduce a:

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

Como sin(90) = 1 y cos(90) = 0 lo simplificamos a:

x, y = -y, x

¡Y ahí lo tienes!


dx, dy = -dy, dx

En caso de duda, aplicar las matemáticas. ;)