可迭代对象 vs 迭代器 vs 生成器

在使用Python的过程中,很容易混淆如下几个关联的概念:

  • 容器(container)
  • 可迭代对象(Iterable)
  • 迭代器(Iterator)
  • 生成器(generator)
  • 生成器表达式
  • {list, set, dict} 解析式

它们之间的关系如下表所示:
在这里插入图片描述

容器(container)

容器是用来储存元素的一种数据结构,它支持隶属测试,容器将所有数据保存在内存中,在Python中典型的容器有:

  • list, deque, …
  • set,frozesets,…
  • dict, defaultdict, OrderedDict, Counter, …
  • tuple, namedtuple, …
  • str

容器相对来说很好理解,因为你可以把它当成生活中的箱子、房子、船等等。
一般的,通过判断一个对象是否包含某个元素来确定它是否为一个容器。例如:

>>> assert 1 in [1,2,3]       # lists
>>> assert 4 not in [1,2,3]
>>> assert 1 in {1,2,3}       # sets
>>> assert 4 not in {1,2,3} 
>>> assert 1 in (12,3)        # tuples
>>> assert 4 not in (1,2,3)

字典容器通过检查是否包含键来进行判断:

>>> d = {1:"foo", 2:"bar", 3:"qux"}
>>> assert 1 in d
>>> assert 4 not in d
>>> assert "foo" not in d

字符串通过检查是否包含某个子 串来判断:

>>> s ="foobar"
>>> assert "b" in s
>>> assert "x" not in s
>>> assert "foo" in s

注意:并非所有的容器都是可迭代对象。

可迭代对象

正如前面所提到的,大部分容器都是可迭代的,但是还有其他一些对象也可以迭代,例如,文件对象以及管道对象等等,容器一般来说存储的元素是有限的,同样的,可迭代对象(持有__iter__魔术方法)也可以用来表示一个包含有限元素的数据结构。

可迭代对象可以为任意对象,不一定非得是基本数据结构,只要这个对象可以返回一个iterator。听起来可能有点费解,但是可迭代对象与迭代器之间有一个显著的区别。先看下面的例子:

>>> x = [1,2,3]
>>> y = iter(x)
>>> z = iter(x)
>>> next(y)
1
>>> next(y)
2
>>> next(z)
1
>>> type(x)
<class 'list'>
>>> type(y)
<class 'list_iterator'>

在这里,x是可迭代对象,而y和z都是迭代器,它们从可迭代对象x中获取值。

注意:可迭代的类中,一般实现以下两个方法(实现迭代协议),iter()以及__next()__方法,iter()方法返回self。

当我们运行以下代码的时候:

x = [1,2,3]
for elem in x:
     ...

实际调用过程如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值