web-dev-qa-db-fra.com

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

En Python, j'ai vu deux valeurs de variable échangées à l'aide de cette syntaxe:

left, right = right, left

Est-ce considéré comme la méthode standard pour échanger deux valeurs de variables ou existe-t-il un autre moyen par lequel deux variables sont, par convention, le plus souvent permutées?

299
WilliamKF

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

http://docs.python.org/3/reference/expressions.html#evaluation-order

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

  • le membre de droite 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 identificateurs b et a, qui existaient avant l’instruction de l’instruction lors de l’exécution du programme.
  • juste après la création de ce tuple, aucune assignation de cet objet 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 assigné au côté gauche
  • comme le membre de gauche est composé de deux identifiants, le Tuple est décompressé afin que le premier identifiant a soit attribué au premier élément du Tuple (qui est l'objet qui était formellement b avant l'échange car il s'appelait b)
    et le deuxième identifiant b est attribué 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 échangé les objets affectés aux identificateurs a et b.

Donc, pour répondre à votre question: OUI, c’est le moyen standard d’échanger deux identifiants sur deux objets.
Soit dit en passant, les objets ne sont pas des variables, ils sont des objets.

344
eyquem

C'est la méthode standard pour échanger deux variables, oui.

104
Martijn Pieters

Je connais trois méthodes pour échanger des variables, mais a, b = b, a est la plus simple. Il y a

XOR (pour les entiers)

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

Ou concise,

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

Variable temporaire

w = x
x = y
y = w
del w

Échange de tuple

x, y = y, x
33
NoOneIsHere

Je ne dirais pas que c’est une méthode standard d’échange car elle entraînera des erreurs inattendues.

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

nums[i] sera d'abord modifié, puis affectera la deuxième variable nums[nums[i] - 1].

16
Yi Huang

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 Permuter les tranches des tableaux Numpy

4
gizzmole

Pour contourner les problèmes expliqués par eyquem , vous pouvez utiliser le module copy pour renvoyer un tuple contenant des copies (inversées) des valeurs, via une fonction:

from copy import copy

def swapper(x, y):
  return (copy(y), copy(x))

Même fonction qu'un lambda:

swapper = lambda x, y: (copy(y), copy(x))

Ensuite, assignez ces noms aux noms souhaités, comme ceci:

x, y = swapper(y, x)

REMARQUE: si vous le souhaitez, vous pouvez importer/utiliser deepcopy au lieu de copy.

0
LogicalBranch