2016-03-30 5 views
2

Я просто понял, что питонический обмен не всегда работает.pythonic swap x, y = y, x не работает?

def swap(x,y): 
    x,y = y,x 

a = 1 
b = 2 
swap(a,b) 

print b 

Результат: 2

Почему вещий способ поменять местами переменные не работает в этом случае? Мне нужна временная переменная?

+1

Что именно вы ожидаете? 'print b' действительно напечатает' 2' becuase 'b = 2' – Deusdeorum

+2

большинство объектов python не изменяются ... ergo вы фактически не обмениваетесь ... вы просто создаете локальную переменную x, y внутри функции, такую, что 'x = y, y = x', но он действует только в то время как вы находитесь в области метода –

+1

@JoranBeasley. Это не имеет ничего общего с изменчивостью. Поведение будет таким же, если вы прошли в списках для этой функции. – timgeb

ответ

1

Вы никогда не возвращались и не назначали результаты. В противном случае, как сказал Йоран, вы создаете локальные переменные в функции. Например: отображается

def swap(a, b): 
    print "swap called" 
    return (b,a) 

a = 1 
b = 2 

print a,b 
a,b = swap(a,b) 
print a,b 

Результаты в следующем:

 
1 2 
swap called 
2 1 
+1

Другими словами, python имеет значение pass-by-value. –

+0

@JamesBuck no, python - это передача по заданию. – timgeb

+0

@timgeb это пропускная способность так же, как C и Java. Более точно описывается как пропускная способность. –

3

В первой строке определения функции

def swap(x,y): 

x и y так называемые формальные параметры. Когда вы звоните

swap(a, b) 

вы передаете в a и b в качестве фактических аргументов.

Что происходит сейчас в том, что Python создает новые имена для фактических параметров вы прошли в.

Внутри тела функции x теперь новое название для целого объекта в памяти, которая также имеет название a. y - теперь новое имя целочисленного объекта в памяти, которое также имеет название b. Вот почему Python не является ни по умолчанию, ни по вызову, но лучше всего описывается как call-by-assignment.

Вопреки распространенному мнению, вызывающие функции и назначение работают точно так же, как и для изменяемых и неизменяемых параметров. Вы увидите то же самое поведение, которое вы наблюдаете за изменяемые значения:

>>> def swap(x,y): 
...  x,y = y,x 
... 
>>> a = [1] 
>>> b = [2] 
>>> swap(a,b) 
>>> a 
[1] 
>>> b 
[2] 

Поэтому, как только вы понимаете, как присваивании в Python, вы также поняли, как вызовы функций работы.

Для примера: Если вы не написали функцию, ваш код был бы эквивалентен:

a = 1 
b = 2 
x = a 
y = b 
x,y = y,x 
del x 
del y 

В строке 3, вы создаете новое имя x для целого объекта, который также идет по названию a. Строка 4 следует той же логике.

В строке 5 вы создаете кортеж (y, x) со значением (2, 1) с правой стороны, который затем распаковывается, т. Е.имя x является переназначен к значению 2 и имя y переназначен на значение 1:

>>> a = 1 
>>> b = 2 
>>> x = a 
>>> y = b 
>>> x,y = y,x 
>>> x 
2 
>>> y 
1 

Важно отметить здесь, что a и b никогда не переставали быть именами для значения 1 и 2 соответственно:

>>> a 
1 
>>> b 
2 

последние две строки просто отвязать имена x и y что примерно эквивалентно тому, что происходит в вашей функции после выхода его объема. Обратите внимание, что имена a и b по-прежнему связаны после развязывания x и y.

>>> a 
1 
>>> b 
2 
Смежные вопросы