这一篇是 《流畅的 python》 读书笔记。主要介绍元组、分片、序列赋值以及引用了大师 Edsger W.Dijkstra 为什么序列从0开始计数 的解释。

元组

在有些python 的介绍中,元组被称为 不可变列表 ,这其实是不准确的,没有完全概括元组的特点。元组除了用作不可变列表,还可以用于 没有字段名的记录 。

元组和记录

元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个数据的位置。

如果把元组当作一些字段的集合,数量和位置信息会变得非常重要。比如以下几条用元组表示的记录:

>>> lax_coordinates = (33.9425, -118.408056) # 洛杉矶国际机场的经纬度

# 东京的一些信息:市名、年份、人口、人口变化和面积

>>> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)

以上这两个元组每个位置都对应一个数据记录。

元组拆包

>>> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)

这个例子中,我们把元组的数据用一条语句分别赋值给 city, year, pop, chg, area,这就是元组拆包的一个具体应用。

元组拆包可以应用到任何可迭代对象上,但是被迭代的对象窄的元素的数量必须跟接受这些元素的元组的空档数一致。

比如:

>>> lax_coordinates = (33.9425, -118.408056)

>>> latitude, longitude = lax_coordinates

>>> latitude

33.9425

>>> longitude

-118.408056

还可以用 * 运算符把一个可迭代对象拆开作为函数的参数:

>>> divmod(20, 8)

(2, 4)

>>> t = (20, 8)

>>> divmode(*t)

(2, 4)

>>> quotient, remainder = divmode(*t)

>>> quotient, remainder

(2, 4)

在进行拆包是,我们可能对元组的某些值并不感兴趣,这时可以用 _ 占位符处理。比如:

>>> divmode(20, 8)

(2, 4)

>>> _, remainder = divmode(20, 8) # 这里我们只关心第二个值

>>> remainder

4

在处理函数参数时,我们经常用 *args 来表示不确定数量的参数。在 python3 中,这个概念被扩展到了平行赋值中:

# python 3 代码示例

>>> a, b, *rest = range(5)

>> a, b, rest

(0, 1, [2, 3, 4])

# * 前缀只能用在一个变量名前,这个变量可以在其他位置

>>> a, *rest, c, d = range(5)

>> a, rest, c, d

(0, [1, 2], 3, 4)

>>> a, b, *rest = range(2)

>> a, b, rest

(0, 1, [])

元组也支持嵌套拆包,比如:

>>> l = (1, 2, 3, (4, 5))

>>> a, b, c, (d, e) = l

>>> d

4

>>> 5

4

具名元组

元组作为记录除了位置以外还少一个功能,那就是无法给字段命名, namedtuple 解决了这个问题。

namedtuple 使用方式实例:

>>> from collecitons import namedtuple

>>> city = namedtuple('City', 'name country population coordinates')

>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

>>> tokyo.population # 可以使用字段名获取字段信息

36.933

>>> tokyo[1] # 也可以使用位置获取字段信息

'JP'

>>> City._fields # _fields 属性是一个包含这个类所有字段名的元组

('name', 'country', 'population', 'coordinates')

>>> tokyo_data = ('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

>>> tokyo = City._make(tokyo_data) # _make() 方法接受一个可迭代对象生成这个类的实例,和 City(*tokyo_data) 作用一致

>>> tokyo._asdict() # _asdict() 把具名元组以 collections.OrderedDict 的形式呈现

OrderedDict([('name', 'Tokyo'), ('country', 'JP'), ('population', 36.933), ('coordinates', (35.689722, 139.691667))])

collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类。 namedtuple 构建的类的实例锁消耗的内存和元组是一样的,因为字段名都被存放在对应的类里。这个实例和普通的对象实例相比也更小一些,因为 在这个实例中,Python 不需要用 __dict__ 来存放这些实例的属性

切片

Python 中列表、元组、字符串都支持切片操作。

在切片和区间操作里不包含区间范围的最后一个元素是 Python 的风格。这样做的好处如下: * 当只有最后一个位置信息时,我们可以快速看出切片和区间里有几个元素:range(3) 和 mylist[:3] 都只返回三个元素 * 当气质位置可见时,可以快速计算出切片和区间的长度,用后一个数减去第一个下标(stop-start)即可。 * 这样还可以让我们利用任意一个下标来把序列分割成不重复的两部分,只要写成 mylist[:x] 和 mylist[x:] 就可以。

切片除了开始和结束的下标之外还可以有第三个参数,比如: s[a:b:c] ,这里 c 表示取值的间隔,c 还可以为负值,负值意味着反向取值。

>>> s = 'bicycle'

>>> s[::3]

'bye'

>>> s[::-1]

'elcycib'

>>> s[::2]

'eccb'

a:b:c 这种用法只能作为索引或者下标在[] 中返回一个切片对象:slice(a, b, c)。对 seq[start:stop:step] 进行求值的时候,Python 会调用 seq. getitem (slice(start:stop:step)]。

给切片赋值

如果把切片放在赋值语句的左边,或者把它作为 del 操作的对象,我们就可以对序列进行嫁接、切除或修改操作,比如:

>>> l = list(range(10))

>>> l

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> l[2:5] = [20, 30]

>>> l

[0, 1, 20, 30, 5, 6, 7, 8, 9]

>>> del l[5:7]

[0, 1, 20, 30, 5, 8, 9]

>>> l[3::2] = [11, 22]

>>> l

[0, 1, 20, 11, 5, 22, 9]

>>> l[2:5] = 100

Traceback (most recent call last):

file "", line 1 in

TypeError: can only assign an iterable

如果赋值的对象是一个切片,那么赋值语句的右侧必须是一个可迭代对象。

给切片命名

如果代码中已经出现了大量的无法直视的硬编码切片下标,可以使用给切片命名的方式清理代码。比如你有一段代码要从一个记录字符串中几个固定位置提取出特定的数据字段 比如文件或类似格式 :

### 01234567890123456789012345678901234567890123456789012345678901234

record = '............100....513.25........'

cost = int(record[20:23]) * float(record[31:37])

# 这时,可以先给切片命名,以避免大量无法理解的硬编码下标,使代码可读性更强

SHARES= slice(20, 23)

PRICE = slice(31, 37)

cost = int(record[SHARES]) * float(record[PRICE])

slice() 函数创建了一个 切片对象 ,可以被用在任何切片允许使用的地方,比如:

>>> items = [0, 1, 2, 3, 4, 5, 6]

>>> a = slice(2, 4)

>>> items[2:4]

[2, 3]

>>> items[a]

[2, 3]

>>> items[a] = [10, 11]

>>> items

[0, 1, 10, 11, 4, 5, 6]

如果你有一个切片对象 a,还可以调用 a.start, a.stop, a.step 来获取更多信息,比如:

>>> a = slice(5, 50, 2)

>>> a.start

5

>>> a.step

2

扩展阅读 为什么下标要从0开始

Python 里的范围(range)和切片都不会反悔第二个下标所指的元素,计算机科学领域的大师 Edsger W.Dijkstra 在一个很短的备忘录 Why numbering should start at zero 里对这一惯例做了说明。以下是部分关键说明:

为了表示出自然数的子序列,2, 3, … , 12,不使用省略记号那三个点号,我们可以选择4种约定方式:

a) 2 ≤ i < 13

b) 1 < i ≤ 12

c) 2 ≤ i ≤ 12

d) 1 < i < 13

是否有什么理由,使选择其中一种约定比其它约定要好呢?是的,确实有理由。可以观察到,a) 和 b)有个优点, 上下边界的相减得到的差,正好等于子序列的长度 。另外,作为推论,下面观察也成立:在 a),b)中, 假如两个子序列相邻的话,其中一个序列的上界,就等于另一个序列的下界 。但上面观察,并不能让我们从a), b)两者中选出更好的一个。让我们重新开始分析。

一定存在最小的自然数。假如像b)和d)那样,子序列并不包括下界,那么当子序列从最小的自然数开始算起的时候,会使得下界进入非自然数的区域。这就比较丑陋了。所以对于下界来说,我们更应该采用≤,正如a)或c)那样。 现在考虑,假如子序列包括上界,那么当子序列从最小的自然数开始算起,并且序列为空的时候,上界也会进入非自然数的区域。这也是丑陋的。所以,对于上界,我们更应该采用 <, 正如a)或b)那样。因此我们得出结论,约定a)是更好的选择。

比如要表示 0, 1, 2, 3 如果用 b) d) 的方式,下界就要表示成 -1 < i

如果一个空序列用 c) 其实是无法表示的,用 a) 则可以表示成 0 ≤ i < 0

总结

这一篇主要介绍元组、分片、序列赋值以及对 为什么序列从0开始计数 做了摘录。

参考链接

最后,感谢女朋友支持。

欢迎关注(April_Louisa)

请我喝芬达

python元组_Python 元组和分片相关推荐

  1. python元组_Python元组

    python元组 Today we are going to learn about Python Tuple. This is very similar to Python List. If you ...

  2. python元组添加元素_Python 元组_python元组操作_添加元素_python 元组转字符串

    Python 元组 Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup1 ...

  3. python创建空元组_Python——元组的基本语法(创建、访问、修改、删除)

    原标题:Python--元组的基本语法(创建.访问.修改.删除) Python 元组的使用 Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号 ( ),列表使用方括号 [ ...

  4. python 元组_python 元组操作总结

    Python 的元组和列表类似,不同之处在于元组中的元素不能修改(因此元组又称为只读列表),元组使用原括号括起. 1.元组中只包含一个元素时,需要在元素后边添加一个逗号消除歧义. 2.元组中的值是不允 ...

  5. c 提取引号中间的字符串_Python | 一文看懂Python列表、元组和字符串操作

    好文推荐,转自CSDN,原作星辰StarDust 序列 序列是具有索引和切片能力的集合. 列表.元组和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力. 列表.元组.字符串都属于序列 ...

  6. angular 字符串转换成数字_Python | 一文看懂Python列表、元组和字符串操作

    好文推荐,转自CSDN,原作星辰StarDust 序列 序列是具有索引和切片能力的集合. 列表.元组和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力. 列表.元组.字符串都属于序列 ...

  7. python列表添加元组_python 列表与元组的操作简介

    列表 列表是可变的(mutable)--可以改变列表的内容,这不同于字符串和元组,字符串和元组都是不可变的.接下来讨论一下列表所提供的方法. list函数 可以使用list函数来创建列表: list( ...

  8. python元组索引_Python 元组、列表

    Python中,最常用的数据结构就是序列了.序列有以下几种:元组,列表,字符串等.注:代码都是在IDE中编辑的,没有用交互式环境. 一.元组(tuple) 元组其实有点类似C++中的数组,即一旦指定了 ...

  9. python元组元素的提取比_Python 元组数据类型(tuple)详解 [访问元组元素][修改元组元素][删除元组][学习 Python 必备基础知识][看此一篇就够了]...

    您的"关注"和"点赞",是信任,是认可,是支持,是动力...... 如意见相佐,可留言. 本人必将竭尽全力试图做到准确和全面,终其一生进行修改补充更新. 1 元 ...

最新文章

  1. java的工厂类_深入理解Java的三种工厂模式
  2. 在AE10.1环境下调试其他版本的程序
  3. 转载:SVN插件的手动安装
  4. Strom的trident单词计数代码
  5. 计算机网络资料篇(二)——快速理解网络协议
  6. 【BZOJ4254】Aerial Tramway 树形DP
  7. Cucumber+Rest Assured快速搭建api自动化测试平台
  8. 一个空间配置多个虚拟主机
  9. c语言提高,C语言提高-day2
  10. LeetCode 542. 01 矩阵
  11. leetcode 148. Sort List
  12. tcp三次握手和在局域网中使用 awl伪装MAC地址进行多线程SYN攻击
  13. strace ltrace使用
  14. 处理得怎么样填空词语_武都网络推广软件效果怎么样【易商网络】
  15. 洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩阵游戏
  16. php对接监控摄像头源码,摄像头监控录像源代码 (详细的代码,可以直接使用,也可以拿来学习使用)...
  17. ES2015新语法详解——生成器(Generator)
  18. Flak执行端口被占用OSError: [Errno 48] Address already in use
  19. 在控制台打印不完整的解决问题
  20. 购买阿里云服务器完整流程及注意事项(图文教程)

热门文章

  1. 零售药店计算机操作内容培训,零售药店gsp培训计划.doc
  2. Cisco服务器http显示内容,IOS HTTP服务器的AAA控制
  3. 影响未来十年的2020十大科技趋势,除了AI与区块链,还有哪些?
  4. 毕业设计 : 基于深度学习的口罩佩戴检测【全网最详细】 - opencv 卷积神经网络 机器视觉 深度学习
  5. iOS逆向工程-工具篇
  6. 教你急速快速批量插入1000万条数据到mysql数据库表面试题
  7. Android广告轮播图效果实现
  8. linux 运行go文件路径,go程序部署到linux上运行-Go语言中文社区
  9. 推荐中的ctr校准方式
  10. 大二学生JavaScript实训大作业——动漫秦时明月7页 期末网页制作 html css javascript 网页设计实例 企业网站制作