首先抛出一个困扰本人许久的问题:

nums = [1,2,3,4,5,6]
numsIter = iter(nums)
for _ in zip(*[numsIter]*3):
print(_)
print(list(numsIter))

则控制台输出如何?

关于迭代器

  1. 对于支持迭代的集合对象,可以创建其迭代器对象。迭代器对象储存了可迭代对象的地址和遍历的位置,迭代器对象从集合的第一个元素开始访问,所有的元素被访问完迭代器被消耗(仍然占地址),但清空储存的信息(即地址和遍历位置)。使用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)) 时输出为空,因为迭代器对象已经找不到地址了。

  2. 复制迭代器对象,得到的是一个迭代器对象的引用,即地址,而不是新建一个迭代器。因此,遍历位置是共同的。
    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对象时,当然是会消耗掉储存的迭代器,使得再一次解压时返回为空。

    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,就是利用了迭代器储存的遍历位置,逐一地获取数据,直到其中一个迭代器被消耗掉。文首的问题就是最好的例子 。

    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() 会直接遍历完毕从而消耗掉迭代器。
    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的一些细节的更多相关文章

  1. 一篇文章掌握 Python 内置 zip() 的全部内容

    一篇文章掌握 Python 内置 zip() 的全部内容 zip() 是 Python 中最好用的内置类型之一,它可以接收多个可迭代对象参数,再返回一个迭代器,可以把不同可迭代对象的元素组合起来. 我 ...

  2. Python迭代器,可迭代对象,生成器

    迭代器 迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节. ...

  3. python迭代器与iter()函数实例教程

    python迭代器与iter()函数实例教程 发布时间:2014-07-16编辑:脚本学堂 本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程 ...

  4. Python中的zip()与*zip()函数详解

    前言 实验环境: Python 3.6: 示例代码地址:下载示例: 本文中元素是指列表.元组.字典等集合类数据类型中的下一级项目(可能是单个元素或嵌套列表). zip(*iterables)函数详解 ...

  5. 一文搞懂Python迭代器和生成器

    很多童鞋搞不懂python迭代器和生成器到底是什么?它们之间又有什么样的关系? 这篇文章就是要用最简单的方式让你理解Python迭代器和生成器! 1.迭代器和迭代过程 维基百科解释道: 在Python ...

  6. python中使用zip函数出现<zip object at 0x02A9E418>

    在Python中使用zip函数,出现<zip object at 0x02A9E418>错误的原因是,你是用的是python2点多的版本,python3.0对python做了改动 zip方 ...

  7. Python 标准库 urllib2 的使用细节

    刚好用到,这篇文章写得不错,转过来收藏.    转载自 道可道 | Python 标准库 urllib2 的使用细节 Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节 ...

  8. 道可叨 | Python 标准库 urllib2 的使用细节

    道可叨 | Python 标准库 urllib2 的使用细节 request = urllib2.Request(uri) request.add_header('User-Agent', 'fake ...

  9. Python 迭代器和列表解析

    Python 迭代器和列表解析 1)迭代器 一种特殊的数据结构,以对象形式存在 >>> i1 = l1.__iter__() >>> i1 = iter(l1) 可 ...

随机推荐

  1. 常用Java API: ArrayList(Vector) 和 LinkedList

    摘要: 本文主要介绍ArrayList(Vector)和LinkedList的常用方法, 也就是动态数组和链表. ArrayList ArrayList 类可以实现可增长的对象数组. 构造方法 Arr ...

  2. 字符串与模式匹配算法(六):Needleman–Wunsch算法

    一.Needleman-Wunsch 算法 尼德曼-翁施算法(英语:Needleman-Wunsch Algorithm)是基于生物信息学的知识来匹配蛋白序列或者DNA序列的算法.这是将动态算法应用于 ...

  3. JAVA笔记12__字节、字符缓冲流/打印流/对象流/

    /** * !!:以后写流的时候一定要加入缓冲!! * 对文件或其它目标频繁的读写操作,效率低,性能差. * 缓冲流:好处是能更高效地读写信息,原理是将数据先缓冲起来,然后一起写入或读取出来. * * ...

  4. JAVA笔记7__接口应用/Object类/简单工厂模式/静态代理模式/适配器模式

    /** * 接口应用 */ public class Main { public static void main(String[] args) { Person p = new Person(&qu ...

  5. hdu 5101 Select (二分+单调)

    题意: 多多有一个智商值K. 有n个班级,第i个班级有mi个人.智商分别是v1,v2,.....vm. 多多要从这些人中选出两人.要求两人智商和大于K,并且两人不同班.问总共有多少种方案. 数据范围: ...

  6. CentOS 7 tmpwatch 2.11 版本变更,移除 cronjob 任务

    老版本(RHEL6) tmpwatch 原理 在 RHEL6 上,/tmp 目录的清理工作通常是交给 tmpwatch 程序来完成的,tmpwatch 的工作机制是通过 /etc/cron.daily ...

  7. 痞子衡嵌入式:聊聊i.MXRT1xxx上的普通GPIO与高速GPIO差异及其用法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT上的普通GPIO与高速GPIO差异. GPIO 可以说是 MCU 上最简单最常用的外设模块了,当一些原生功能外设接口模块不能 ...

  8. AppGallery Connect场景化开发实战—注册订阅通知

    借助AppGallery Connect(以下简称AGC)的认证服务,云函数,短信服务等服务,当用户注册成功后,便可以在注册的手机号或者邮箱地址中收到一条应用的欢迎短信或者欢迎邮件.以便让开发者更快地 ...

  9. FZU_DS_2019_SequenceList

    单选题 2-1   数组A[1..5,1..6]每个元素占5个单元,将其按行优先次序存储在起始地址为1000的连续的内存单元中,则元素A[5,5]的地址为:  A.1120      B.1125   ...

  10. IDEA maven Run Maven 启动方式

    首先想要使用 Run Maven 启动需要在IDEA设置里找到plugins  在plugins窗口下面找到Browse Repositories   打开Browse Repositories 下载 ...