415 votes

Existe-t-il une méthode standardisée pour permuter deux variables en Python ?

En Python, j'ai vu deux valeurs de variables interverties en utilisant cette syntaxe :

left, right = right, left

S'agit-il de la manière standard d'échanger les valeurs de deux variables ou existe-t-il un autre moyen par lequel deux variables sont par convention le plus souvent échangées ?

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.

497voto

eyquem Points 9942

Python évalue les expressions de gauche à droite. Remarquez que pendant d'une affectation, le côté droit est évalué avant le côté gauche. côté gauche.

Docs Python : Ordre d'évaluation

Cela signifie ce qui suit pour l'expression a,b = b,a :

  • Le côté droit b,a est évalué, c'est-à-dire qu'un tuple de deux éléments est créé dans la mémoire. Les deux éléments sont les objets désignés par les identifiants b y a qui existaient avant que l'instruction ne soit rencontrée pendant l'exécution du programme.
  • Juste après la création de ce tuple, aucune affectation de cet objet tuple n'a encore été faite, mais cela n'a pas d'importance, Python sait en interne où il se trouve.
  • Ensuite, le côté gauche est évalué, c'est-à-dire que le tuple est affecté au côté gauche.
  • Comme le côté gauche est composé de deux identifiants, le tuple est décomposé de manière à ce que le premier identifiant a est assigné au premier élément du tuple (qui est l'objet qui était précédemment b avant l'échange parce qu'il avait le nom b )
    et le deuxième identifiant b est affecté au deuxième élément du tuple (qui est l'objet qui était auparavant a avant l'échange car ses identifiants étaient a )

Ce mécanisme a effectivement permuté les objets attribués aux identifiants a y b

Donc, pour répondre à votre question : OUI, c'est la façon standard de permuter deux identifiants sur deux objets.
D'ailleurs, les objets ne sont pas des variables, ce sont des objets.

1 votes

D'après ce que j'ai compris, le fait de permuter deux variables de cette manière n'utilise PAS de mémoire supplémentaire, seulement de la mémoire pour les deux variables elles-mêmes, n'est-ce pas ?

4 votes

@Catbuilts La construction du tuple occupera un peu plus de mémoire (probablement plus que la version à 3 variables de l'échange), mais comme les seules choses échangées sont des adresses mémoire, ce ne sera pas beaucoup de mémoire supplémentaire dans le sens absolu (peut-être 24 octets supplémentaires).

0 votes

@Brilliand : Merci. Avez-vous des documents sur ce sujet ? C'est assez intéressant et j'aimerais le lire plus avant. Merci.

126voto

Martijn Pieters Points 271458

C'est la façon standard d'échanger deux variables, oui.

42voto

NoOneIsHere Points 413

Je connais trois façons d'échanger des variables, mais a, b = b, a est le plus simple. Il y a

XOR (pour les entiers)

x = x ^ y
y = y ^ x
x = x ^ y

Ou de manière concise,

x ^= y
y ^= x
x ^= y

Variable temporaire

w = x
x = y
y = w
del w

Échange de tuple

x, y = y, x

33voto

Yi Huang Points 279

Je ne dirais pas qu'il s'agit d'une méthode standard de permutation, car elle peut entraîner des erreurs inattendues.

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]

nums[i] sera modifiée en premier et affectera ensuite la deuxième variable nums[nums[i] - 1] .

8voto

gizzmole Points 505

Ne fonctionne pas pour les tableaux multidimensionnels, car les références sont utilisées ici.

import numpy as np

# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)

# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)

Voir aussi Échanger des tranches de tableaux Numpy

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