dbd*_*bdq 18 python iterator loops list enumerate
我知道我不应该在循环中修改列表,但出于好奇,我想知道为什么以下两个示例之间的迭代次数不同.
例1:
x = [1, 2, 3, 4, 5]
for i, s in enumerate(x):
del x[0]
print(i, s, x)
Run Code Online (Sandbox Code Playgroud)
例2:
x = [1,2,3,4,5]
for i, s in enumerate(x):
x = [1]
print(i, s, x)
Run Code Online (Sandbox Code Playgroud)
示例1仅运行3次,因为何时i==3,len(x)==2.
尽管示例2运行了5次len(x)==1.
所以我的问题是,是否在循环开始时enumerate生成完整的(index, value)对列表并迭代它?或者它们是在循环的每次迭代中生成的?
Wis*_*ind 22
在第一个示例中,您实际上正在修改正在迭代的列表.
另一方面,在第二种情况下,您只是为名称分配一个新对象x.但是,循环迭代的对象不会改变.
有关Python中名称和变量的更详细说明,请查看http://foobarnbaz.com/2012/07/08/understanding-python-variables/.
Was*_*mad 17
enumerate()返回一个迭代器或一些支持迭代的其他对象.enumerate()返回的迭代器的 __next __()方法返回一个包含count的元组(从start开始,默认为0)和迭代迭代得到的值.
__next __()返回容器中的下一个项目.如果没有其他项目,请提出StopIteration异常.
enumerate()是否在循环开始时生成(索引,值)对的完整列表并迭代它?或者它们是在循环的每次迭代中生成的?
因此,enumerate()返回一个迭代器,并在每次迭代时__next__()检查是否还有其他项.enumerate()不会在循环开始时创建完整列表.
正如@Wisperwind所提到的那样,在你的第二种情况下,你要为名称分配一个新对象x.循环迭代的对象在迭代期间不会改变.
只是澄清了Wasi Ahmad和Wisperwind所说的话.两者都声明"您只是将新对象分配给名称x".这可能有点令人困惑,因为它可能被解释为"你正在创建一个新对象([1])并将其存储到名称中x,你会说"好吧,为什么它不会改变?!"看看发生了什么,打印出对象的id
x = [1, 2, 3, 4, 5]
y = x # To keep a reference to the original list
print id(x), id(y)
for i, v in enumerate(x):
x = [1]
print id(x), id(y)
print id(x), id(y)
# output (somewhat contrived as I don't have a python environment set up)
# X ID Y ID
10000000000001 10000000000001
10000000000002 10000000000001
10000000000003 10000000000001
10000000000004 10000000000001
10000000000005 10000000000001
10000000000006 10000000000001
10000000000006 10000000000001
Run Code Online (Sandbox Code Playgroud)
你会注意到id的x是通过循环改变每次当你与循环结束后,x将指向循环的最后一次修改.当你完成循环时,它会迭代x的原始实例,无论你是否仍然可以引用它.
如您所见,y指向原始x.当您通过循环进行迭代时,即使x正在改变,y仍然指向x仍在循环的原始循环.