这段代码是完全有效的 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 中,函数具有单个本地范围(就像在控制台中在全局级别输入的代码一样)。
代码正常的原因是您在将外部值e
重新绑定到内部值之前完成了使用;尝试查看打印的内容:
x=[[1,2,3,4], [11,22,33,44]]
for e in x:
for e in e:
print e
print e
e
只是一个标签。外循环的每次迭代都e
被分配第n
th 值x
,并且每次内循环迭代都被分配第m
th 值x[n]
。这是完全有效的 Python 代码,只是从样式的角度来看是不可取的,因为除了一个简单的示例之外,它很快就会使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 ...
,...
通过迭代器协议转换为迭代器。您实际迭代的对象是与您最初提供的对象不同的对象。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))
因为第二个e
绑定在第一个e
评估到列表之后。因此,所有其他迭代步骤都不是从变量中获取项目,而是从列表中获取项目。例如,在下一个代码中重新评估e
对迭代没有影响:
for e in x:
for i in e:
print i
e = [8, 8, 8]
坦率地说,我没有发现这个问题的任何当前答案是令人满意的。我认为根本的解释是 Python 将 for 循环作用域作为一种特殊情况处理。
看起来 Python 认识到 for 循环变量是特殊的,并且在 for 循环结束时,根据需要将变量的当前值复制到封闭范围。
这解释了为什么可以编写以下代码:
for i in range(3):
i = 5
print("hello")
它将执行3次。for 循环变量 i 是特殊的,与赋值为 5 的变量 i不同。
Python 可能将其视为:
for i_12349678 in range(3):
i = 5
print("hello")
对于使用相同变量 i 的嵌套 for 循环:
for i in range(3):
for i in range(4):
print("i = %s" % i)
Python 可能认为它更像:
for i_18987982221 in range(3):
for i_9870272721 in range(4):
print("i = %s" % i_9870272721)
更多信息: http: //mail.python.org/pipermail/python-ideas/2008-October/002109.html
在这种情况下,“e”在同一范围内。如果你做类似...
for i in range(MAX):
if(some_condition == True):
for i in range(5):
#do stuff
如果代码遍历到内部 for 循环,它将增加“外部 i”5 次,导致您跳过这些运行。
使用您发布的代码,它不会产生语法错误,并且从逻辑角度来看它恰好可以解决,但可能还有其他示例您会得到错误的结果。