Python3高级特性(五)之容器(container)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Python3高级特性(五)之容器(container)

容器(container)


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

在Python中,常见的容器对象有:

1)      list, deque, ….

2)      set, frozensets, ….

3)      dict, defaultdict, OrderedDict, Counter, ….

4)      tuple, namedtuple, …

5)      str

容器比较容易理解,因为可以把它看作是一个盒子,里面可以塞任何东西。从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,dict, set,tuples都是容器对象。

容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。但凡是可以返回一个迭代器的对象都可称之为可迭代对象,

迭代器(iterator)


那么什么迭代器呢?它是一个带状态的对象,能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。迭代器就是实现了工厂模式的对象,它在每次询问要下一个值的时候给你返

生成器(generator)


生成器简介


生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。

生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。它特殊的地方在于函数体中没有return关键字,函数的返回值是一个生成器对象,只有显示或隐示地调用next的时候才会真正执行里面的代码。

生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码,相比其它容器对象它更能节省内存和CPU,当然它可以用更少的代码来实现相似的功能。

yield案例


生成器对象是一个迭代器:但是它比迭代器对象多了一些方法,它们包括send方法,throw方法和close方法。这些方法,主要是用于外部与生成器对象的交互。

send方法有一个参数:该参数指定的是上一次被挂起的yield语句的返回值。

案例如下:

def MyGenerator():
    receive = yield 100
    print('extra' + str(receive))
    receive = yield 200
    print('extra' + str(receive))
    receive = yield 300
    print('extra' + str(receive))
gen = MyGenerator()
print(next(gen))  #也可以用:print(gen.send(None))
print("first")
print(gen.send(2))
print("second")
print(gen.send(3))
print("third")
复制代码

输出:100  first   extra2   200    second   extra3    300   third

注意,yield语句是最具魔力的表达式:这里“yield 100”整体被视为一个表达式,send的内容会作为这个表达式的值,随便左边用什么变量接收或者不接收,总之yield就是send进来的那个值。这个表达式变成send进来后的那个值之后,继续往下执行,直到再次遇到yield,挂起。

如何启动生成器呢?调用(gen.next()或gen.send(None))上面代码的运行过程如下。

当调用gen.next()方法时:python首先会执行MyGenerator方法的yield 1语句。由于是一个yield语句,因此方法的执行过程被挂起,而next方法返回值为yield关键字后面表达式的值,即为100。

当调用gen.send(2)方法时:python首先恢复MyGenerator方法的运行环境。同时,将表达式(yield 100)的返回值定义为send方法参数的值,即为2。这样,接下来value=(yield 100)这一赋值语句会将value的值设为2。继续运行会遇到yield value语句,MyGenerator方法再次被挂起。同时,send方法的返回值为yield关键字后面表达式的值,也即value的值,为200。

当调用gen.send(3)方法时:首先恢复MyGenerator方法的运行环境。同时,将表达式(yield value)的返回值定义为send方法参数的值,即为3。这样,接下来value=(yield 200)这一赋值语句会将value的值置为3。继续运行,MyGenerator方法执行完毕。以此类推….

总的来说:

send方法和next方法唯一的区别,在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。当然,下面的代码是可以接受的:

gen = MyGenerator() 
print( gen.send(None) )
复制代码

因为当send方法的参数为None时,它与next方法完全等价。但是注意,虽然上面的代码可以接受,但是不规范。所以,在调用send方法之前,还是先调用一次next方法为好。


作者:zhulin1028

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章
|
1月前
|
开发者 Docker Python
深入浅出:使用Docker容器化部署Python Web应用
在当今快速发展的软件开发领域,Docker作为一个开放平台,为开发者提供了将应用打包在轻量级、可移植的容器中的能力,从而简化了部署和管理应用程序的复杂性。本文将通过一个简单的Python Web应用示例,引导读者理解Docker的基本概念、容器化的优势以及如何使用Docker来容器化部署Python Web应用。我们将从零开始,逐步探索创建Dockerfile、构建镜像、运行容器等关键步骤,旨在为读者提供一个清晰、易于理解的指南,帮助他们掌握使用Docker容器化部署应用的技能。
|
12天前
|
程序员 索引 Python
06-python数据容器-set(集合)入门基础操作
06-python数据容器-set(集合)入门基础操作
|
12天前
|
索引 容器
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
|
1月前
|
存储 Python 容器
Python-数据容器
Python-数据容器
12 3
|
2月前
|
NoSQL Redis Docker
深入浅出:使用Docker容器化改进Python应用部署
在快速演进的软件开发领域,持续集成和持续部署(CI/CD)已成为加速产品上市的关键。本文将探索如何利用Docker,一种流行的容器化技术,来容器化Python应用,实现高效、可靠的部署流程。我们将从Docker的基本概念入手,详细讨论如何创建轻量级、可移植的Python应用容器,并展示如何通过Docker Compose管理多容器应用。此外,文章还将介绍使用Docker的最佳实践,帮助开发者避免常见陷阱,优化部署策略。无论是初学者还是有经验的开发人员,本文都将提供有价值的见解,助力读者在自己的项目中实现容器化部署的转型。
|
2月前
|
存储 Python 容器
python数据容器之字典相关的操作
python数据容器之字典相关的操作
17 2
python数据容器之字典相关的操作
|
2月前
|
存储 Python 容器
python数据容器之集合相关的操作
python数据容器之集合相关的操作
20 1
|
2月前
|
存储 索引 Python
python数据容器之列表相关的操作
python数据容器之列表相关的操作
24 1
|
2月前
|
持续交付 开发者 Docker
深入浅出:使用Docker容器化改进Python应用部署
在当今快速变化的软件开发领域,开发者面临着各种挑战,其中之一就是如何确保应用在不同环境中都能稳定运行。本文将介绍Docker这一容器化技术如何为Python应用提供一个一致的运行环境,简化部署过程,并提高开发效率和应用的可移植性。我们将从Docker的基本概念讲起,通过实际案例演示如何将一个简单的Python应用容器化,最后探讨容器化对于持续集成/持续部署(CI/CD)流程的积极影响。