このコードは完全に有効な Python です
x=[[1,2,3,4], [11,22,33,44]]
for e in x:
for e in e:
print e
誰かが理由と、これがどのように機能するか教えてもらえますか?
両方e
の が異なるスコープにあることは理解していますが、このようにそれらを一緒に使用してもエラーが発生しないのはなぜですか?
このコードは完全に有効な Python です
x=[[1,2,3,4], [11,22,33,44]]
for e in x:
for e in e:
print e
誰かが理由と、これがどのように機能するか教えてもらえますか?
両方e
の が異なるスコープにあることは理解していますが、このようにそれらを一緒に使用してもエラーが発生しないのはなぜですか?
スコープは同じです。Python では、関数は単一のローカル スコープを持ちます (コンソールでグローバル レベルで入力されたコードと同様)。
コードが OK である理由はe
、内部の値に再バインドする前に外部の値の使用を終了するためです。これが何を出力するか見てみてください:
x=[[1,2,3,4], [11,22,33,44]]
for e in x:
for e in e:
print e
print e
e
は単なるラベルです。外側のループの各反復にはから 番目e
の値が割り当てられ、内側のループの各反復にはから 番目の値が割り当てられます。これは完全に有効な Python コードですが、スタイルの観点からはお勧めできません。単純な例を除けば、コードのどの時点で何を表しているのかがすぐにわかりにくくなり、バグにつながる可能性があるからです。n
x
m
x[n]
e
上記の式の内部ループを大まかに次のように変換できると思います。
for e in x:
ee = iter(e)
try:
e = next(ee)
while True
print e
e = next(ee)
except StopIteration
pass
ここで重要なことはステートメントにあることに注意してください: はfor e in ...
、iterator protocol...
を介して iterator に変換されます。実際に反復するオブジェクトは、最初に指定したオブジェクトとは別のオブジェクトです。これは別のオブジェクトなので (現在のスコープでその名前とは別に保存され、反復できるようになっています)、新しい変数を現在のスコープでその名前にバインドしても問題はありません。問題はないと言うべきかもしれません。それ以外は、コードを理解するのが本当に難しくなります。e
これは、これを行うのに問題がないのと事実上同じ理由です。
A = [['foo']] #Define A
b = A[0] #Take information from A and rebind it to something else
c = A #We can even take the entire reference and bind/alias it to a new name.
A = 'bar' #Re-assign A -- Python doesn't care that A already existed.
考慮すべき点がいくつかあります。
x = [1,2,3,4]
for a in x:
print a
next(a) #Raises an error because lists aren't iterators!
現在ではめったに使用されません (ただし、必要な場合もあります) 慣用句:
x = [1,2,3,4]
y = iter(x) #create an iterator from the list x
for a in y:
print a
#This next line is OK.
#We also consume the next value in the loop since `iter(y)` returns `y`!
#In fact, This is the easiest way to get a handle on the object you're
#actually iterating over.
next(y)
最後に:
x = [1,2,3,4]
y = iter(x) #create an iterator from the list x
for a in y:
print a
#This effectively does nothing to your loop because you're rebinding
#a local variable -- You're not actually changing the iterator you're
#iterating over, just as `A = 'bar'` doesn't change the value of
#the variable `c` in one of the previous examples.
y = iter(range(10))
firstがリストに評価された後にsecondがe
バインドされるためです。e
したがって、他のすべての反復ステップは、変数からではなくリストから項目を取得します。たとえば、次のコードでは、再割り当てe
は反復に影響しません。
for e in x:
for i in e:
print i
e = [8, 8, 8]