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

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. MIPI的走线阻抗

    MIPI的走线阻抗100欧的要求是根据LVDS(Low Voltage Differential Signaling)电平定义的. LVDS差分信号PN两线最大幅度是350mV,内部一个恒流源电流是3 ...

  2. oeasy教您玩转vim - 56 - # 字符可视化模式

    ​ 可视化编辑 回忆上节课内容 我们学习了关于模式匹配中使用参数 单个参数 :%s/<h2>\(.*\)</h2>/ - \1/g 多个参数 :%s/<img src=\ ...

  3. nohup java -jar xx.jar & ,关闭窗口后退出进程

    nohup java -jar dw-report..jar > dw-report.log  & 自动退出命令在后台运行 xx.jar程序 明明已经加了"&" ...

  4. python编程中的流程控制

    内容概要 成员运算 身份运算 流程控制 详细 1.成员运算 定义:判断某个个体在不在某个群体内 关键词:in(在) /// not in(不在) 例: num_list = [1, 2, 3, 4, ...

  5. LeetCode Weekly Contest 266

    第一题 题解:模拟题 class Solution { public: int countVowelSubstrings(string w) { int n = w.length(); int i = ...

  6. 将python代码转化为c语言代码,提高运行效率

    将python代码转化为c语言代码,提高运行效率 首先,需要安装cpython库: pip install cython 安装完成之后,写一段简单的代码,例如下面这个利用递归求斐波那契数列的函数,然后 ...

  7. 大一C语言学习笔记(4)---自省篇

    博主"曾经"做过的傻事: #你有的*没打全 #你用/的时候没考虑()是一对的 #printf随后加\n #所有变量只要用,就一定要定义数据类型 #sqrt()代表根号 #inclu ...

  8. Part 18 $http service in AngularJS

    In Angular there are several built in services. $http service is one of them. In this video, we will ...

  9. Effective C++ 总结笔记(五)

    六.继承与面向对象设计 32.确定你的public继承塑模出is-a关系 public继承意味着is-a.适用于base class身上的每一件事情也一定适用于derived class身上.每一个d ...

  10. Linux驱动实践:带你一步一步编译内核驱动程序

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...