Python | 迭代器与zip的一些细节
首先抛出一个困扰本人许久的问题:
nums = [1,2,3,4,5,6]
numsIter = iter(nums)
for _ in zip(*[numsIter]*3):
print(_)
print(list(numsIter))
则控制台输出如何?
关于迭代器
- 对于支持迭代的集合对象,可以创建其迭代器对象。迭代器对象储存了可迭代对象的地址和遍历的位置,迭代器对象从集合的第一个元素开始访问,所有的元素被访问完迭代器被消耗(仍然占地址),但清空储存的信息(即地址和遍历位置)。使用list()函数或 * 操作符可以获取所有遍历的内容,结束后迭代器被消耗。
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)) 时输出为空,因为迭代器对象已经找不到地址了。
- 复制迭代器对象,得到的是一个迭代器对象的引用,即地址,而不是新建一个迭代器。因此,遍历位置是共同的。
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
- 在创建zip对象时,并没有直接生成新数据,而是存储了要操作对象的迭代器,当真正需要的时候,才通过迭代器遍历数据。因此,当使用list()函数或 * 操作符解压zip对象时,当然是会消耗掉储存的迭代器,使得再一次解压时返回为空。
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)]
[] zip之所以能work,就是利用了迭代器储存的遍历位置,逐一地获取数据,直到其中一个迭代器被消耗掉。文首的问题就是最好的例子 。
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)) 发现迭代器确实已经被消耗。
- 当使用 print 显示迭代器或zip对象的内容时,list() 和 * 操作符几乎没有区别。但上述例子中,只能用 * 操作符来实现,因为 * 操作符实际上是返回对象的地址和遍历位置,而 list() 会直接遍历完毕从而消耗掉迭代器。
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()函数的同时,掌握了一个将一维数据变为二维数据的方法。
Python | 迭代器与zip的一些细节的更多相关文章
- 一篇文章掌握 Python 内置 zip() 的全部内容
一篇文章掌握 Python 内置 zip() 的全部内容 zip() 是 Python 中最好用的内置类型之一,它可以接收多个可迭代对象参数,再返回一个迭代器,可以把不同可迭代对象的元素组合起来. 我 ...
- Python迭代器,可迭代对象,生成器
迭代器 迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节. ...
- python迭代器与iter()函数实例教程
python迭代器与iter()函数实例教程 发布时间:2014-07-16编辑:脚本学堂 本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程 ...
- Python中的zip()与*zip()函数详解
前言 实验环境: Python 3.6: 示例代码地址:下载示例: 本文中元素是指列表.元组.字典等集合类数据类型中的下一级项目(可能是单个元素或嵌套列表). zip(*iterables)函数详解 ...
- 一文搞懂Python迭代器和生成器
很多童鞋搞不懂python迭代器和生成器到底是什么?它们之间又有什么样的关系? 这篇文章就是要用最简单的方式让你理解Python迭代器和生成器! 1.迭代器和迭代过程 维基百科解释道: 在Python ...
- python中使用zip函数出现<zip object at 0x02A9E418>
在Python中使用zip函数,出现<zip object at 0x02A9E418>错误的原因是,你是用的是python2点多的版本,python3.0对python做了改动 zip方 ...
- Python 标准库 urllib2 的使用细节
刚好用到,这篇文章写得不错,转过来收藏. 转载自 道可道 | Python 标准库 urllib2 的使用细节 Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节 ...
- 道可叨 | Python 标准库 urllib2 的使用细节
道可叨 | Python 标准库 urllib2 的使用细节 request = urllib2.Request(uri) request.add_header('User-Agent', 'fake ...
- Python 迭代器和列表解析
Python 迭代器和列表解析 1)迭代器 一种特殊的数据结构,以对象形式存在 >>> i1 = l1.__iter__() >>> i1 = iter(l1) 可 ...
随机推荐
- 计算机网络之网络层IP组播(IGMP、组播路由选择协议、组播地址)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105318560 学习课程:<2019王道考研计算机网络> 学习目的 ...
- 攻防世界 web1.view_source
右键不管用,F12打开控制台,直接查看flag.
- switch中case...用法-c语言
... 表示范围 case 0...4; // error case 5 ... 9; // ok eg 1: char ch = 4; switch(ch) { case 1: printf(& ...
- 如何反编译微信小程序👻
如何反编译微信小程序 准备工具: 夜神模拟器(或者你可以自己准备一个安卓模拟器,有root权限.) RE文件管理器(下载地址:https://soft.ucbug.com/uploads/shouji ...
- NOIP模拟88(多校21)
前言 对于这套题的总体感觉就是难,然后就是自己很菜... 对于 T1 考试时只会一个最垃圾的背包,考完之后对于思路这一块也不是很顺利,大概这就是薄弱的地方吧. 然后 T2 是比较简单的一道题了,但是考 ...
- linux系列之: 你知道查看文件空间的两种方法吗?
目录 简介 du命令 df命令 总结 简介 linux系统中查看文件空间大小应该是一个非常常见的命令了,今天给大家介绍linux系统中查看文件空间的两种方法和在使用中可能会遇到的奇怪问题. 为什么会有 ...
- 【死磕 NIO】— Proactor模式是什么?很牛逼吗?
大家好,我是大明哥. 上篇文章我们分析了高性能 IO模型Reactor模式,了解了什么是Reactor 模式以及它的三种常见的模式,这篇文章,大明再介绍另外一种高性能IO模型: Proactor. 为 ...
- 二.什么是Promise
二.什么是Promise 1.理解 2.promise 的状态改变 3.promise的基本流程 4.promise的基本使用 1.理解 抽象表达: Promise 是JS 中进行异步编程的新的解决方 ...
- String你会用吗?
1. 如果不是在循环体中进行字符串拼接的话,直接使用 String 的 "+" 就好了. 2. 单线程循环中操作大量字符串数据 → StringBuilder.append() 3 ...
- 环境(6)Linux文件系统二
一:计算机间的数据传输 windows---linux : lrzsz :需要手动安装 yum install lrzsz -y ; rz 将文件从window上传到linux : ...