假设我们有以下列表,我们正在为它创建一个迭代器:
lst = [1,2,3]
itr = iter(lst)
接下来假设我们正在使用完全不同的值更改列表:
lst = ['a', 'b', 'c']
如果我运行以下循环:
for x in itr:
print x
我们将获得'1,2,3'
。但为什么?据我所知,迭代器不会复制迭代对象的所有值。至少三个元素列表的迭代器与100000个元素的列表具有相同的大小。 sys.getsizeof(i)
返回64
。如何使迭代器的大小如此之小并保持列表的“旧”值?
答案 0 :(得分:4)
迭代器本身包含对列表的引用。由于ssh-rsa <key> <email>
是反弹而不是变异,因此该引用不会改变。
lst
答案 1 :(得分:3)
迭代器引用列表对象而不是名称。所以将名称>>> import gc
>>> lst = [1,2,3]
>>> itr = iter(lst) # return an iterator for the list
>>> lst = ['a', 'b', 'c'] # Bind name lst to another object
>>> gc.get_referents(itr)[0]
[1, 2, 3]
重新分配给另一个对象不会影响迭代器;名称绑定到对象,并引用对象,但名称不是对象本身。
您可以使用Counter获取迭代器引用的对象的窥探:
read_csv
正如您所注意到的,迭代器仍然是指第一个列表对象。
以下参考资料将帮助您了解有关Python中名称和绑定的更多信息:
答案 2 :(得分:2)
欢迎使用Python的对象参考系统。变量名与存储在内存中的实际对象并没有很深的关系。
假设您有一个朋友lst
,并且您雇用抢劫 iter
来抢劫他。现在你告诉抢劫犯你的朋友是电话簿中的第三个杰克(globals
)。
lst = [1, 2, 3]
itr = iter(lst) # iter object now points to the list pointed to by lst
# it doesn't care about its name (doesn't even knows its name actually)
# Now the mugger has found the friend, and knows his address (the actual object in memory).
# The mugger catches him, and takes his jacket.
print itr.next() # outputs 1
# Now the telephone directory was updated (yes it's updated very frequently).
lst1 = lst # your friend is now the fourth Jack
lst = ['a', 'b', 'c'] # someone else is the third Jack now
# but mugger doesn't know, he won't see the directory again
print itr.next() # (output 2), mugger takes t-shirt, and leaves him for now
# Meanwhile your friend buys new clothes.
lst1.append(4) # here the actual object pointed to by iter is updated
lst1.append(5)
# You call the mugger and say, don't leave him until he's got nothing.
# The mugger goes full retard.
for i in iter:
print i # outputs 3, 4 and 5
NTL; DR :Python变量名只是标记,指的是空间中的某个对象。
当您在名为iter
的{{1}}上调用list
时,迭代器对象类获取指向实际对象的指针,即使现在它的名称也是{{1} }。
如果您可以通过调用lst
,lst
,append
,extend
等来修改原始对象,则会影响迭代器行为。但是,当您为pop
分配新值时,会创建一个新对象(如果它之前不存在),并且remove
只是开始指向该新对象。
如果没有其他对象指向它,垃圾收集器将删除原始对象(在这种情况下lst
指向它,因此原始对象不会被删除)。
http://foobarnbaz.com/2012/07/08/understanding-python-variables/
额外:
lst
这与对象引用没有任何关系,迭代器只在内部存储它迭代完整列表。