首先抛出一个困扰本人许久的问题:
1
2
3
4
5
|
nums = [ 1 , 2 , 3 , 4 , 5 , 6 ]
numsIter = iter (nums)
for _ in zip ( * [numsIter] * 3 ):
print (_)
print ( list (numsIter))
|
则控制台输出如何?
关于迭代器
1.对于支持迭代的集合对象,可以创建其迭代器对象。迭代器对象储存了可迭代对象的地址和遍历的位置,迭代器对象从集合的第一个元素开始访问,所有的元素被访问完迭代器被消耗(仍然占地址),但清空储存的信息(即地址和遍历位置)。使用list()函数或 * 操作符可以获取所有遍历的内容,结束后迭代器被消耗。
1
2
3
4
5
6
|
nums = [ 1 , 2 , 3 , 4 , 5 , 6 ]
numsIter = iter (nums)
print (nums)
print ( list (nums))
print (nums)
print ( list (nums))
|
输出为:
<list_iterator object at 0x00000205944619D0>
[1,2,3,4,5,6]
<list_iterator object at 0x00000205944619D0>
[]
第二次键入 print(list(nums)) 时输出为空,因为迭代器对象已经找不到地址了。
2.复制迭代器对象,得到的是一个迭代器对象的引用,即地址,而不是新建一个迭代器。因此,遍历位置是共同的。
1
2
3
4
5
6
7
8
|
nums = [ 1 , 2 , 3 , 4 , 5 , 6 ]
numsIter = iter (nums)
numsIter_list = [numsIter] * 2
print (numsIter)
print (numsIter_list)
for _ in numsIter_list:
print ( next (_))
|
输出为:
<list_iterator object at 0x0000020594445A00>
[<list_iterator object at 0x0000020594445A00>, <list_iterator object at 0x0000020594445A00>]
1
2
关于zip
1.在创建zip对象时,并没有直接生成新数据,而是存储了要操作对象的迭代器,当真正需要的时候,才通过迭代器遍历数据。因此,当使用list()函数或 * 操作符解压zip对象时,当然是会消耗掉储存的迭代器,使得再一次解压时返回为空。
1
2
3
4
5
6
|
P = [ 1 , 2 , 3 ]
Q = [ 4 , 5 , 6 ]
PQ_zip = zip (P,Q)
print (PQ_zip)
print ( list (PQ_zip))
print ( list (PQ_zip))
|
输出为:
<zip object at 0x0000020594520140>
[(1, 4), (2, 5), (3, 6)]
[]
2.zip之所以能work,就是利用了迭代器储存的遍历位置,逐一地获取数据,直到其中一个迭代器被消耗掉。文首的问题就是最好的例子 。
1
2
3
4
5
|
nums = [ 1 , 2 , 3 , 4 , 5 , 6 ]
numsIter = iter (nums)
for _ in zip ( * [numsIter] * 3 ):
print (_)
print ( list (numsIter))
|
输出为:
(1, 2, 3)
(4, 5, 6)
[]
可以看见,实现的功能是把单行数据变成了3列2行。这是怎么做到的呢?执行zip时,依次访问三个同样的迭代器,每次访问,迭代器的遍历位置都会加1,于是第一轮结束后zip获取了(1,2,3),同理第二轮则获取了(4,5,6),随后迭代器被消耗。第三轮zip对象已经没有迭代器可用,于是结束执行。最后 print(list(numsIter)) 发现迭代器确实已经被消耗。
3.当使用 print 显示迭代器或zip对象的内容时,list() 和 * 操作符几乎没有区别。但上述例子中,只能用 * 操作符来实现,因为 * 操作符实际上是返回对象的地址和遍历位置,而 list() 会直接遍历完毕从而消耗掉迭代器。
1
2
3
4
5
6
|
nums = [ 1 , 2 , 3 ]
numsIter = iter (nums)
print (numsIter)
for _ in zip ( list (numsIter) * 3 ):
print (_)
print ( list (numsIter))
|
输出为:
<list_iterator object at 0x0000020594445B80>
(1,)
(2,)
(3,)
(1,)
(2,)
(3,)
(1,)
(2,)
(3,)
[]
总结:
在熟悉迭代器和zip()函数的同时,掌握了一个将一维数据变为二维数据的方法。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://www.cnblogs.com/wsy950409/p/15485341.html