web-dev-qa-db-ja.com

Pythonの複数の割り当てと評価順序

次のPython式の違いは何ですか:

# First:

x,y = y,x+y

# Second:

x = y
y = x+y

最初とは異なる結果を与えます。

例えば。、

最初:

>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3

2番目:

>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4

y最初で3、第二で4

46
rafuru

代入文では、変数の実際の設定を行う前に、右側が常に完全に評価されますbefore。そう、

x, y = y, x + y

yを評価し(結果hamを呼び出しましょう)、x + yを評価します(spamを呼び出します)、thenxhamに、yspamに設定します。つまり、それは

ham = y
spam = x + y
x = ham
y = spam

対照的に、

x = y
y = x + y

xyに設定してから、yx(これは== y)とyに設定します。したがって、

x = y
y = y + y
73
Fred Foo

それは "評価順序" :というタイトルのセクションのドキュメントで説明されています。

...割り当ての評価中、右側が左側の前に評価されます。

12
unutbu

最初の式:

  1. y,x+yで一時的なタプルを作成します
  2. 別の一時的なタプルに割り当てられました
  3. タプルを変数xおよびyに抽出します

2番目のステートメントは、実際にはTupleを使用しない2つの式です。

驚いたことに、最初の表現は実際には:

temp=x
x=y
y=temp+y

コンマの使用法の詳細については、「 Parenthesized forms 」をご覧ください。

4
Abhijit

私は最近Pythonを使い始めました。この「機能」は私を困惑させました。多くの答えが与えられましたが、とにかく私の理解を投稿します。

JavaSciptで2つの変数の値を交換する場合は、次のようにします。

var a = 0;
var b = 1;

var temp = a;
a = b;
b = temp;

値の1つを一時的に保持する3番目の変数が必要です。両方の変数が同じ値になるため、非常に単純なスワップは機能しません。

var a = 0;
var b = 1;

a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1

2つの異なる(赤と青の)バケツを持ち、それぞれに2つの異なる液体(水と油)があると想像してください。次に、バケツ/液体(青の水、赤のバケツの油)を交換してみてください。余分なバケットがない限り、実行できません。

Pythonは、これを「よりクリーンな」方法/ソリューションで処理します: Tuple Assignment

a = 0
b = 1

print(a, b) # 0 1

# temp = a
# a = b
# b = temp

a, b = b, a # values are swapped

print(a, b) # 1 0

このようにすると、Pythonは "temp"変数を自動的に作成するので、心配する必要はありません。

1
akinuri

2番目のケースでは、x+yxに割り当てます

最初のケースでは、2番目の結果(x+y)がyに割り当てられます

これが異なる結果を得る理由です。

編集後

これは、ステートメントで

x,y = y,x+y

右側のメンバーのすべての変数が評価され、左側のメンバーに保存されます。したがって、firstは右のメンバーに進み、secondは左のメンバーに進みます。

2番目のステートメント

x = y
y = x + y

yoは最初にyを評価し、それをxに割り当てます。そのように、x+yの合計はy+yの合計と等しく、x+xの合計は最初のケースではありません。

1
DonCallisto

最初のものは、タプルのような割り当てです。

x,y = y,x+y

ここで、xはTupleの最初の要素であり、yは2番目の要素です。したがって、あなたがしていることは:

x = y
y = x+y

2番目は、直接割り当てを行っています。

x=y
x=x+y
1
Serdalis
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b

出力

1
1
2
3
5
8

変数aとbは同時に新しい値0と1を取得し、同じa、b = b、a + b、aとbが同時に割り当てられます。

0
li bing zhao

違いを見てみましょう。

x, y = y, x + yそれはx Tuple xssignment、mexns (x, y) = (y, x + y)、 と同じように (x, y) = (y, x)

XからのStxrtの簡単な例:

x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1

(x, y) = (y, x + y) ExFP、xに直接試行させる

x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2

しかしながら、

In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5

結果は最初の試行とは異なります。

Thxは、Pythonが最初に右側のx+yしたがって、次と同等です。

old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c

要約すれば、 x, y = y, x+y 手段、
xは、yのold_valueを取得するために交換します。
yは、古い値xと古い値yの合計を取得するために交換します。

0
Algebra