热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

序列不包含任何匹配元素_流畅的Python笔记(第2章):序列构成的数组

本章讨论的内容几乎可以应用到所有的序列类型上,从我们熟悉的list,到Python3中的特有的str和bytes。还会提到跟列表、元组、数组及队列有关的

本章讨论的内容几乎可以应用到所有的序列类型上,从我们熟悉的list,到Python3中的特有的str和bytes。还会提到跟列表、元组、数组及队列有关的话题。深入理解Python的不同序列类型,不但能让我们避免重新发明轮子,它们的API还能帮助我们把自己定义的API设计得跟原生的序列一样,或者是跟未来可能出现的序列类型保持兼容。

内置序列类型概览

序列类型可以按照存放数据的类型分类:

容器序列

  • list
  • tuple
  • collections.deque

扁平序列

  • str
  • bytes
  • bytearray
  • memoryview
  • array.array

容器序列存放的是它们所包含的任意类型的对象的引用,而扁平序列里存放的是值而不是引用。换句话说,扁平序列其实是一段连续的内存空间。由此可见扁平序列其实更加紧凑,但是它里面只能存放诸如字符、字节和数值这种基础类型。

序列类型还能按照能否被修改类分类:

可变序列

  • list
  • bytearray
  • array.array
  • collections.deque
  • memoryview

不可变序列

  • tuple
  • str
  • bytes
ef46304d9543d053144dd5bb629e9431.png

上图显示了可变类型(mutableSequence)和不可变类型(Sequence)的差异,同时可以看出前者从后者那里继承了一些方法。

列表推导

请看示例代码:

>>> i=2
>>> i
2
>>> [i for i in 'abc']
['a', 'b', 'c']
>>> i
c

Python2中,在列表推导中for关键词之后的赋值操作可能会影响列表推导上下文中的同名变量,示例中i的值被取代了,但是这种情况再Python3中是不会出现的。

生成器表达式

生成器表达式遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。显然使用生成器表达式方法更能够节省内存。

>>> (i for i in 'abc')
at 0x10842c4c0>

生成器表达式的语法跟列表推导差不多,只不过把方括号改成圆括号而已。

元组不仅仅是不可变列表

有些Python入门教程把元组成为"不可变列表",然而这病没有完全概括元组的特点。除了用作不可变的列表,它还可以用于没有字段名的记录。

元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个字段的位置。正是这个位置信息给数据赋予了意义。

如果只把元组理解为不可变的列表,那其他信息(元素总数和它的位置)似乎就变得可有可无。

元组拆包

>>> a, b, c = (1, 2, 3)
>>> a
1
>>> b
2
>>> c
3

元组拆包可有应用到任何可迭代对象上,唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接受这些元素的元组空挡数一致。

命名元组

collections.namedtuple是一个工厂函数,它可有用来构建一个带字段名的元组和一个有名字的类。 示例如下:

>>> Card = namedtuple("Card", ['rank', 'suit'])
>>>
>>> a = Card(1,2)
>>> a.rank
1

切片

在Python里,list、tuple和str这类序列类型都支持切片操作。 切片语法暂不详述。

对序列使用+和*

Python默认序列是支持+和*操作的,两侧的序列由相同类型的数据构成,在拼接的过程中,两个被操作的序列都不会修被修改,Python会新建一个包含同样数据类型的序列来作为拼接的结果。

>>>a = [1, 2]
>>>a * 3
[1, 2, 1, 2, 1, 2]
>>> 2 * 'abc'
'abcabc'

序列的增量赋值

增量赋值运算符+=和*=的表现取决于它们的第一个操作对象。 +=背后的特殊方法是__iadd_。但是如果类没有实现这个方法的话,Python会退一步调用__add__。 示例代码:

>>> a = (1, 2, [3, 4])
>>> a
(1, 2, [3, 4])
>>> a[2] += [6, 7]
Traceback (most recent call last):File "", line 1, in
TypeError: 'tuple' object does not support item assignment
>>> a
(1, 2, [3, 4, 6, 7])

这个示例中,因为tuple不支持对他的元素赋值,所以会抛出TypeError异常。但是由于a[2]是个列表,本身是支持+=操作的,所以a的值变成了(1, 2, [3, 4, 6, 7])。

总结:

  • 不要把可变对象放在元组里面。
  • 增量赋值不是一个原子操作。我们刚才看到它虽然抛出了异常,但还是完成了操作。

list.sort方法和内置函数sorted

list.sort方法会就地排序列表,也就是说不会把原列表复制一份。

与list.sort相反的内置函数sorted,它会新建一个列表作为返回值。

用bisect来管理已排序的序列

bisect模块包含两个主要函数,bisect和insort,两个函数都利用二分查找算法来在有序序列中查找或插入元素。

  • bisect:在有序序列中查找某个元素的插入位置。
  • insort:向有序序列中插入新元素,并保持排序。

双向队列

collections.deque类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。



推荐阅读
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文介绍了在C#中SByte类型的GetHashCode方法,该方法用于获取当前SByte实例的HashCode。给出了该方法的语法和返回值,并提供了一个示例程序演示了该方法的使用。 ... [详细]
author-avatar
r_elease靜
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有