嵌套循环中不同值的相同变量名称。

时间:2012-11-06 16:38:09

标签: python

此代码完全有效的Python

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

有人可以告诉我原因,以及它是如何运作的?

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

6 个答案:

答案 0 :(得分:6)

范围没有差别;在Python中,函数只有一个局部作用域(在控制台的全局级别输入代码)。

代码正常的原因是,在将其重新绑定到内部值之前,您已完成使用e的外部值;试着看看这个打印的内容:

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

答案 1 :(得分:3)

e只是一个标签。外部循环e的每次迭代都会从n分配x个值,并且每个内部循环迭代都会为m分配x[n]个值}。它是完全有效的Python代码,从样式的角度来看是不可取的,因为除了一个简单的例子之外,它很快就会混淆e代表代码中的哪一点,因此很可能导致错误。

答案 2 :(得分: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 ......通过iterator protocol转换为迭代器。您实际迭代的对象是与您最初提供的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))

答案 3 :(得分:1)

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

for e in x:
    for i in e:
        print i
        e = [8, 8, 8]

答案 4 :(得分:0)

坦率地说,我没有发现这个问题目前的任何答案都令人满意。我认为潜在的解释是Python处理for循环作用域作为一种特殊情况。

看起来Python认识到for循环变量是特殊的,并且在for循环结束时,根据需要将变量的当前值复制到封闭范围。

这解释了为什么你可以编写以下代码:

for i in range(3):
    i = 5
    print("hello")

它将执行3次。 for-loop变量i是来自赋值为5的变量i的特殊 distinct

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

答案 5 :(得分:0)

在这种情况下,

'e'属于同一范围。如果你做类似的事情...

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

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

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