完全理解Python迭代对象、迭代器、生成器

1.assert:python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常

2.

容器(container)

容器是一种把多个元素组织在一起的数据结构,

容器中的元素可以逐个地迭代获取,

可以用innot in关键字判断元素是否包含在容器中。

通常这类数据结构把所有的元素存储在内存中

(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:

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

容器比较容易理解,因为你就可以把它看作是一个盒子、一栋房子、一个柜子,里面可以塞任何东西。

从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,

比如 list,set,tuples都是容器对象:

d = {1: 'foo', 2: 'bar', 3: 'qux'}

assert 1 in d
尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,
但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力,
当然并不是所有的容器都是可迭代的,比如:Bloom filter
虽然Bloom filter可以用来检测某个元素是否包含在容器中,但是并不能从容器中获取其中的每一个值,
因为Bloom filter压根就没把元素存储在容器中,而是通过一个散列函数映射成一个值保存在数组中。

可迭代对象(iterable)

>>> 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是一个可迭代对象,可迭代对象和容器一样是一种通俗的叫法,
并不是指某种具体的数据类型,list是可迭代对象,dict是可迭代对象,
set也是可迭代对象。yz是两个独立的迭代器,迭代器内部持有一个状态,
该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。
迭代器有一种具体的迭代器类型,比如list_iteratorset_iterator
可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。

迭代器(iterator)

那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,

任何实现了__iter____next__()(python2中实现next())方法的对象都是迭代器,

__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,

则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。

所以,迭代器就是实现了工厂模式的对象,它在你每次你询问要下一个值的时候给你返回。

有很多关于迭代器的例子,比如itertools函数返回的都是迭代器对象。

生成器(generator)

生成器算得上是Python语言中最吸引人的特性之一,

生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。

它不需要再像上面的类一样写__iter__()__next__()方法了,

只需要一个yiled关键字。 生成器一定是迭代器(反之不成立),

因此任何生成器也是以一种懒加载的模式生成值。用生成器来实现斐波那契数列的例子是:

原文地址:https://www.cnblogs.com/Jt00/p/7447838.html