在循环中更改可迭代变量 [英] Changing iterable variable during loop

查看:131
本文介绍了在循环中更改可迭代变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

it 成为python中的一个可迭代元素。
> 循环中反映的变化或者更简单:什么时候这样的工作?

  it =范围(6)
我在里面:
it.remove(i + 1)
print i

,正在打印2,4(显示循环运行3次)。

另一方面,

 












$



导致输出:

  [0,1,2,3] 
[0,1]
[]
[]
[]
[],

显示循环运行6次。我想这与就地操作或变量作用域有关,但不能100%确定地把我的头围绕着它。



清除:



其中一个例子是:

  it =范围(6)
在这里:
it = it.remove(i + 1)
打印

会导致'None'被打印,并且错误(NoneType没有属性'remove')被抛出。

解决方案>

在迭代 list 时,实际上调用 list .__ iter __() ,它返回绑定到 list listiterator 对象,然后实际遍历这个 listiterator 。从技术上讲,这是:

  itt = [1,2,3] 
for it itt:
打印我

实际上是一种语法糖:

  itt = [1,2,3] 
迭代器= iter(itt)
而真:
尝试:
i = it.next()
除了StopIteration:
break
print i



<因此,在循环内部,重新绑定 itt 不会影响 listiterator 自己对列表的引用),但是 mutating itt 会明显地影响它(因为两个引用指向相同的列表)。 b
$ b

IOW在重新绑定和变异之间是相同的旧区别...没有对于循环,您会得到相同的行为:

 #创建一个`list`并将其绑定到名字a
a = [1,2,3]
#获取绑定到名称a的对象并将其绑定到名称b。
#在这一点上,a和b都指的是相同的`list`实例
b = a
打印id(a),id(b)
打印是b
#所以如果我们改变a - 实际上改变绑定到名称的对象a -
#我们可以看到使用任何引用这个对象的名字的效果:
a.append(42)
print b

#现在我们重新绑定a - 使其引用另一个对象
a = [a,b,c ]
#在这一点上,b仍然是指第一个列表,而
#a是指新的[a,b,c]列表
打印id(a),id(b)
打印a是b
#当然,如果我们现在突变a,它不会反映在b
a .pop()
打印
打印b


Let it be an iterable element in python. In what cases is a change of it inside a loop over it reflected? Or more straightforward: When does something like this work?

it = range(6)
for i in it:
    it.remove(i+1)
    print i

Leads to 0,2,4 being printed (showing the loop runs 3 times).

On the other hand does

it = range(6)
for i in it:
    it = it[:-2]
    print it

lead to the output:

[0,1,2,3]
[0,1]
[]
[]
[]
[],

showing the loop runs 6 times. I guess it has something to do with in-place operations or variable scope but cannot wrap my head around it 100% sure.

Clearification:

One example, that doesn't work:

it = range(6)
for i in it:
    it = it.remove(i+1)
    print it

leads to 'None' being printed and an Error (NoneType has no attribute 'remove') to be thrown.

解决方案

When you iterate over a list you actually call list.__iter__(), which returns a listiterator object bound to the list, and then actually iterate over this listiterator. Technically, this:

itt = [1, 2, 3]
for i in itt:
    print i

is actually kind of syntactic sugar for:

itt = [1, 2, 3]
iterator = iter(itt)
while True:
    try:
        i  = it.next()
    except StopIteration:
        break
    print i

So at this point - within the loop -, rebinding itt doesn't impact the listiterator (which keeps it's own reference to the list), but mutating itt will obviously impact it (since both references point to the same list).

IOW it's the same old difference between rebinding and mutating... You'd get the same behaviour without the for loop:

# creates a `list` and binds it to name "a"
a = [1, 2, 3] 
# get the object bound to name "a" and binds it to name "b" too.
# at this point "a" and "b" both refer to the same `list` instance
b = a 
print id(a), id(b)
print a is b
# so if we mutate "a" - actually "mutate the object bound to name 'a'" - 
# we can see the effect using any name refering to this object:
a.append(42)
print b

# now we rebind "a" - make it refer to another object
a = ["a", "b", "c"]
# at this point, "b" still refer to the first list, and
# "a" refers to the new ["a", "b", "c"] list
print id(a), id(b)
print a is b
# and of course if we now mutate "a", it won't reflect on "b"
a.pop()
print a
print b

这篇关于在循环中更改可迭代变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆