0

这段代码是完全有效的 Python

x=[[1,2,3,4], [11,22,33,44]]
for e in x:
    for e in e:
        print e

有人可以告诉我为什么,以及这是如何工作的吗?

我知道这两个e' 都在不同的范围内,但是如何像这样一起使用它们不会导致错误?

4

6 回答 6

9

范围没有什么不同。在 Python 中,函数具有单个本地范围(就像在控制台中在全局级别输入的代码一样)。

代码正常的原因是您在将外部值e重新绑定到内部值之前完成了使用;尝试查看打印的内容:

x=[[1,2,3,4], [11,22,33,44]]
for e in x:
    for e in e:
        print e
    print e
于 2012-11-06T16:44:22.027 回答
3

e只是一个标签。外循环的每次迭代都e被分配第nth 值x,并且每次内循环迭代都被分配第mth 值x[n]。这是完全有效的 Python 代码,只是从样式的角度来看是不可取的,因为除了一个简单的示例之外,它很快就会使e代码中的什么代表变得混乱,因此很可能导致错误。

于 2012-11-06T16:43:13.997 回答
3

我想您可以将上述表达式中的内部循环大致翻译为:

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))
于 2012-11-06T16:43:25.040 回答
1

因为第二个e绑定在第一个e评估到列表之后。因此,所有其他迭代步骤都不是从变量中获取项目,而是从列表中获取项目。例如,在下一个代码中重新评估e对迭代没有影响:

for e in x:
    for i in e:
        print i
        e = [8, 8, 8]
于 2012-11-06T16:45:20.780 回答
0

坦率地说,我没有发现这个问题的任何当前答案是令人满意的。我认为根本的解释是 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

于 2017-08-17T12:06:23.603 回答
0

在这种情况下,“e”在同一范围内。如果你做类似...

for i in range(MAX):
    if(some_condition == True):
        for i in range(5):
            #do stuff

如果代码遍历到内部 for 循环,它将增加“外部 i”5 次,导致您跳过这些运行。

使用您发布的代码,它不会产生语法错误,并且从逻辑角度来看它恰好可以解决,但可能还有其他示例您会得到错误的结果。

于 2020-10-01T20:03:41.407 回答