38 votes

Y a-t-il un moyen d'écrire ces ifs plus agréables?

Je dois écrire ces quatre if s en Python. Notez ce que cela fait, change entre quatre états possibles dans une boucle: 1,0 -> 0,1 -> -1,0 -> 0,-1 et retour à la première.

 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
 

Quelqu'un peut-il me suggérer un moyen meilleur / plus agréable d'écrire cela?

157voto

Magnus Hoff Points 12052
 dx, dy = -dy, dx
 

En cas de doute, appliquez les mathématiques. ;)

55voto

kindall Points 60645

Magnus " suggestion est indéniablement la bonne réponse à votre question posée, mais en règle générale, vous souhaitez utiliser un dictionnaire pour les problèmes de ce type:

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

dx, dy = statemap[dx, dy]

Même dans ce cas, je pourrais argumenter à l'aide d'un dictionnaire est mieux, car il est clair qu'il y a exactement quatre états, et qu'ils répètent, mais il est difficile de résister à la beauté de toutes les mathématiques.

Par ailleurs, le code dans votre question a un bug, et, en supposant que les valeurs de test pour sont les seules valeurs possibles, est équivalent à:

dx, dy = 1, 0

Le bug, c'est que vous avez besoin d' elif pour la deuxième et les suivantes conditions, sinon, vous êtes en continuant de test dx et dy après leur modification. Si elles sont à l' 1 et 0, alors tous à vos conditions seront les vrais , et ils finissent par la même à la fin! Si ils commencent comme 0 et 1 puis de la deuxième et de toutes les conditions soient vraies, et vous de nouveau à la fin avec l' 1, 0. Et ainsi de suite...

31voto

Andre Rodrigues Points 1501

Juste s'étendant Magnus réponse. Si vous imaginez [dx, dy] comme un vecteur, ce que vous êtes en train de faire une rotation de 90 degrés (ou PI/2).

Pour calculer cela, vous pouvez utiliser la transformation suivante:

two dimensional rotation

Qui, dans votre cas, les traductions:

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

Depuis sin(90) = 1 et cos(90) = 0 nous simplifier ainsi:

x, y = -y, x

Et là vous l'avez!

18voto

Karl Knechtel Points 24349

Les valeurs avec lesquelles vous travaillez apparaissent comme un vecteur unitaire qui tourne en permanence - autrement dit, un phaseur . Les nombres complexes sont des coordonnées , donc:

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

En supposant que mon interprétation de la signification des valeurs dx, dy soit correcte, cela vous donne une flexibilité supplémentaire au cas où il s'avérerait plus tard que vous souhaitiez effectuer une rotation différente de chaque étape.

6voto

yak Points 3938

Alors que j'irais avec la réponse de Magnus, voici encore une autre approche pour la rotation sur un ensemble de valeurs:

 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
 

Notez qu'il devrait y avoir un break quelque part dans la boucle for dx, dy sinon cela ne finira jamais.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X