Cette syntaxe est une façon standard d'échanger des variables. Cependant, nous devons faire attention à l'ordre lorsqu'il s'agit d'éléments qui sont modifiés et ensuite utilisés dans les éléments de stockage suivants de l'échange.
L'utilisation de tableaux avec un index direct ne pose aucun problème. Par exemple :
def swap_indexes(A, i1, i2):
A[i1], A[i2] = A[i2], A[i1]
print('A[i1]=', A[i1], 'A[i2]=', A[i2])
return A
A = [0, 1, 2, 3, 4]
print('For A=', A)
print('swap indexes 1, 3:', swap_indexes(A, 1, 3))
Nous donne :
("Pour A=", [0, 1, 2, 3, 4])
('A[i1]=', 3, 'A[i2]=', 1)
('swap indexes 1, 3:', [0, 3, 2, 1, 4])
Cependant, si nous modifions le premier élément de gauche et l'utilisons dans le deuxième élément de gauche comme un index, cela provoque un mauvais swap.
def good_swap(P, i2):
j = P[i2]
#Below is correct, because P[i2] is modified after it is used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[P[i2]], P[i2] = P[i2], P[P[i2]]
print('Good swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
def bad_swap(P, i2):
j = P[i2]
#Below is wrong, because P[i2] is modified and then used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[i2], P[P[i2]] = P[P[i2]], P[i2]
print('Bad swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
P = [1, 2, 3, 4, 5]
print('For P=', P)
print('good swap with index 2:', good_swap(P, 2))
print('------')
P = [1, 2, 3, 4, 5]
print('bad swap with index 2:', bad_swap(P, 2))
("Pour P=", [1, 2, 3, 4, 5])
("Avant : P[i2]=", 3, "P[P[i2]]=", 4)
('Bon échange : Après P[i2]=', 4, 'P[P[i2]]=', 3)
('good swap with index 2:', [1, 2, 4, 3, 5])
("Avant : P[i2]=", 3, "P[P[i2]]=", 4)
('Bad swap : After P[i2]=', 4, 'P[P[i2]]=', 4)
('bad swap with index 2:', [1, 2, 4, 4, 3])
Le mauvais échange est incorrect car P[i2] est 3 et nous nous attendons à ce que P[P[i2]] soit P[3]. Cependant, P[i2] est d'abord changé en 4, donc le P[P[i2]] suivant devient P[4], ce qui écrase le 4ème élément plutôt que le 3ème.
Le scénario ci-dessus est utilisé en permutations. Un bon et mauvais échange plus simple serait :
#good swap:
P[j], j = j, P[j]
#bad swap:
j, P[j] = P[j], j
1 votes
@eyquem : il s'agit simplement de savoir si ordre d'évaluation est défini par le langage pour une affectation de tuple/liste. Python le fait, la plupart des langages plus anciens ne le font pas.
0 votes
Hrmm C++ a swap(a[i], a[k]) pourquoi ne pouvons-nous pas avoir quelque chose comme ça pour Python.
2 votes
@Nils Parce qu'en Python, l'affectation est une crénelage opération alors que dans l'affectation C++ à une référence est un remplacement opération. Par conséquent, en Python, vous ne pouvez pas remplacer les valeurs des arguments passés à une fonction comme en C++ (vous pouvez seulement les muter). Voir Copie et comparaison : Problèmes et solutions de Grogono et Sakkinen pour une explication de ces termes.