博客
关于我
第4章 基础知识进阶 第4.1节 Python基础概念之迭代、可迭代对象、迭代器
阅读量:111 次
发布时间:2019-02-26

本文共 2513 字,大约阅读时间需要 8 分钟。

第四章 基础知识进阶

第十七节 迭代、可迭代对象、迭代器

一、引言

原本计划在介绍完元组和字典后,接着讲解列表解析和字典解析。但要理解列表解析和字典解析,就必须掌握Python的高级类型迭代器。因此,本节将首先介绍迭代器的概念。

二、概念

迭代是指通过重复执行代码来处理相似的数据集的过程,且本次迭代的处理数据要依赖上一次的结果继续往下做。上一次产生的结果为下一次产生结果的初始状态。如果中途有任何停顿,就不能算作迭代。

1. 迭代与非迭代的区别

  • 非迭代例子

    loop = 0while loop < 3:    print("Hello world!")    loop += 1

    例1仅是循环3次输出"Hello world!",输出的数据不依赖上一次的数据,因此不是迭代。

  • 迭代例子

    loop = 0while loop < 3:    print(loop)    loop += 1

    例2的输出依赖上一次的数据,这就是迭代。

2. 容器

容器是一种将多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取。可以通过innot in关键字判断元素是否包含在容器中。

  • 容器的定义

    在Python中,基本上所有有元素的数据类型(字符串除外)都能包含其他类型的对象。容器的本质是可迭代对象赋予了容器这种能力。

  • 容器与可迭代对象的关系

    容器本身并不提供直接访问元素的能力,而是可迭代对象赋予了容器这种能力。例如,l = [1,2,3,4],我们可以通过for循环遍历它,这是因为列表是可迭代对象。

3. 可迭代对象(Iterable)

可迭代对象并不是指某种具体的数据类型,而是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__()方法或__getitem__()方法访问。

  • __iter__方法

    该方法允许对象用for...in循环遍历,__getitem__()方法允许通过实例名[index]访问实例中的元素。

  • 可迭代对象的使用

    在Python中,任何可迭代对象都可以用for...in循环访问。这实际上是调用了__iter__()方法获得一个迭代器,然后循环调用__next__()方法。

  • 常见的可迭代对象

    包括列表、元组、字典、集合、字符串等。此外,还有一种特殊的可迭代对象——生成器。

4. 判断对象是否为可迭代对象

可以通过collections模块的Iterable类型来判断。例如:

from collections import Iterableisinstance('', Iterable)  # 返回True,表明字符串也是可迭代对象

关于collections后续将有更详细的介绍。

5. 迭代可变对象的注意事项

当在迭代可变对象(如列表)时,迭代器记录当前到达的序列中的第几个元素。如果在迭代过程中修改了序列,更新会立即反映到迭代过程中。例如:

l = [1,2,3,4]i = iter(l)list(i)  # 将迭代器转换为列表,输出[1,2,3,4]list(i)  # 再次转换为列表,输出[]

如果需要多次访问迭代器内容,可以在访问前重新生成迭代器。

6. 迭代器(Iterator)

迭代器可以看作是一个特殊的对象,每次调用该对象时会返回自身的下一个元素。从实现上来看,一个迭代器对象必须定义__iter__()方法和next()方法。

  • 迭代器的特点

    迭代器的计算是惰性的,只有在需要返回下一个数据时才会计算。所有的Iterable可迭代对象均可以通过内置函数iter()转换为迭代器。

  • 迭代器的优点

  • 节省内存(循环过程中,数据不用一次性读入)
  • 不依赖索引取值
  • 实现惰性计算(需要时再计算)
  • 迭代器的使用示例

    # 通过for循环访问迭代器vList = [1,2,3,4]vIter = iter(vList)for i in vIter:    print('第一次:', i)for i in vIter:    print('第二次:', i)

    通过上述代码可以看到,迭代器和可迭代对象的区别。每次for循环访问迭代器时,迭代器会重新开始,从第一个元素开始。

    # 通过next()方法访问迭代器vList = [1,2,3,4]vIter = iter(vList)while True:    try:        i = next(vIter)        print('第一次:', i)    except:        break

    代码中的while循环可以多次调用next(),但注意到每次调用next()时,迭代器都会移动到下一个元素。

  • 迭代器的局限性

    迭代器只能向前访问数据,且一旦访问过,已访问的数据无法再次访问。例如:

    l = [1,2,3,4]i = iter(l)list(i)  # 输出[1,2,3,4]list(i)  # 输出[]

    如果需要多次访问迭代器内容,可以重新生成迭代器。

  • 迭代完成后的异常

    当所有元素都取出后,再次调用next()会抛出StopIteration异常。这并不是错误,而是告诉调用者迭代已经完成。

三、迭代器代码举例

  • 通过for...in方式访问迭代器

    vList = [1,2,3,4]vIter = iter(vList)for i in vIter:    print('第一次:', i)for i in vIter:    print('第二次:', i)

    通过上述代码可以看出,迭代器是一次性的,第二次循环没有输出数据。

  • 通过next()方法访问迭代器

    vList = [1,2,3,4]vIter = iter(vList)while True:    try:        i = next(vIter)        print('第一次:', i)    except:        break

    这段代码可以多次调用next(),但每次调用时迭代器都会移动到下一个元素。

  • 通过本节的介绍,希望大家对迭代器有了清晰的理解,并能够根据实际需求选择适合的方式进行数据处理。

    转载地址:http://qovk.baihongyu.com/

    你可能感兴趣的文章
    Netty源码—6.ByteBuf原理一
    查看>>
    Netty源码—6.ByteBuf原理二
    查看>>
    Netty源码—7.ByteBuf原理三
    查看>>
    Netty源码—7.ByteBuf原理四
    查看>>
    Netty源码—8.编解码原理一
    查看>>
    Netty源码—8.编解码原理二
    查看>>
    Netty源码解读
    查看>>
    Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
    查看>>
    Netty相关
    查看>>
    Netty遇到TCP发送缓冲区满了 写半包操作该如何处理
    查看>>
    Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起?
    查看>>
    Netty:原理架构解析
    查看>>
    Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
    查看>>
    Network Sniffer and Connection Analyzer
    查看>>
    Network 灰鸽宝典【目录】
    查看>>
    NetworkX系列教程(11)-graph和其他数据格式转换
    查看>>
    Networkx读取军械调查-ITN综合传输网络?/读取GML文件
    查看>>
    network小学习
    查看>>
    Netwox网络工具使用详解
    查看>>
    Net与Flex入门
    查看>>