终于进入到第五章数据结构部分了,python中常用的容器有列表、元组、集合和字典,今天主要了解的是最为常用的列表。

5. 数据结构

5.1. 列表的更多特性

对于列表的操作有很多,具体操作看官方文档就行,但是我们对列表有什么操作,是应该有个印象的,否则需要用到的时候不知道有这种操作,自然也谈不上查文档了。

  • 通过list()或者中括号[]新建一个列表;通过clear()删除列表中所有的元素
  • 在列表的末尾添加一个元素xappend(x);在列表中间插入一个元素insert(i, x)
  • 删除并返回列表中的最后一个元素pop()移除列表中第一个值为 x 的元素remove(x)
  • 返回列表中第一个值为 x 的元素的从零开始的索引,也就是查找xindex(x);若要对x计数,返回元素 x 在列表中出现的次数,则用count(x)
  • 对列表中的元素进行排序sort()反转列表中的元素则用reverse()

一些方法示例如下:

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # 从位置4开始查找banana
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'

要注意到两点:

  1. insertremove 或者 sort 方法,只修改列表,没有打印出返回值——它们返回默认值 None ,这是Python中所有可变数据结构的设计原则。
  2. 并非所有数据或可以排序或比较。 例如,[None, 'hello', 10] 就不可排序,因为整数不能与字符串比较,而 None 不能与其他类型比较。 并且还存在一些没有定义顺序关系的类型。 例如,3+4j < 5+7j 就不是一个合法的比较。

5.1.1. 列表作为栈使用

堆栈即最后一个插入的元素,最先取出(“后进先出”)。添加一个元素到堆栈的顶端,使用 append() ;从堆栈顶部取出一个元素,使用 pop()

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

5.1.2. 列表作为队列使用

列表也可以用作队列,其中先添加的元素被最先取出 (“先进先出”);然而列表用作这个目的相当低效。因为在列表的末尾添加和弹出元素非常快,但是在列表的开头插入或弹出元素却很慢 (因为所有的其他元素都必须移动一位)。

若要实现一个队列, collections.deque 被设计用于快速地从两端操作。例如:

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry进队列
>>> queue.append("Graham")          # Graham进队列
>>> queue.popleft()                 # 第一个元素Eric出列
'Eric'
>>> queue.popleft()                 # 第一个元素John出列
'John'
>>> queue                           # 现在的队列
deque(['Michael', 'Terry', 'Graham'])

5.1.3. 列表推导式

列表推导式是更简单的创建列表的方法。常见的用法是把某种操作应用于序列或可迭代对象的每个元素上,然后使用其结果创建列表,或者通过满足某些特定条件元素来创建子序列。

例如,假设我们想创建一个平方列表,用for遍历的话,就像这样:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

它就等价于下面这种列表推导式:

squares = [x**2 for x in range(10)]

列表推导式的结构是:由一对方括号[]包含以下内容:一个表达式,后面跟一个 for 子句,然后是零个或多个 forif 子句。
列表推导式的结果是:一个新列表,由对表达式依据后面的 forif 子句的内容进行求值计算而得出。

举例来说,以下列表推导式会将两个列表中不相等的元素组合起来:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

它等价于:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

这里是更多的例子:

>>> vec = [-4, -2, 0, 2, 4]
>>> # 创建一个将原列表里面的值*2的新列表,
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # 去掉原列表中的负数
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # 对原列表中的所有元素应用一个函数(此处为绝对值函数)
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # 在每个元素上调用一个方法
>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # 创建一个二元的元组如(数字, 数字的平方)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # 元组必须带括号,否则会引发错误
>>> [x, x**2 for x in range(6)]File "<stdin>", line 1, in <module>[x, x**2 for x in range(6)]^
SyntaxError: invalid syntax
>>> # 用带有两个for的列表推导式,使一个二维列表变为一维列表
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

5.1.4. 嵌套的列表推导式

列表推导式中的初始表达式可以是任何表达式,包括另一个列表推导式。

考虑下面这个 3x4的矩阵,它由3个长度为4的列表组成:

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

下面的列表推导式将交换其行和列:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

注意遍历是先i后row。这里如果用zip()可能会更简单点:

>>> list(zip(*matrix))  #星号是解包参数列表,上一讲已经介绍
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

所谓zip(),就是用来组合列表的,例如:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]

zip()是组合,星号*是拆分,两者可以看作是互为逆操作:

>>> x2, y2 = zip(*zip(x, y))  # x2为元组(1,2,3),y2为元组(4,5,6)
>>> x == list(x2) and y == list(y2)
True

5.2. del 语句

前面介绍过删除列表中的元素有popremove,那能不能按照给定的索引而不是值来移除列表中的一个元素呢?可以,使用del语句。
它不同于会返回一个值的 pop() 方法。 del 语句也可以用来从列表中移除切片或者清空整个列表(我们之前用过的方式是将一个空列表赋值给指定的切片)。 例如:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del 甚至可以被用来删除整个变量,删除后再引用 a 时就会报错:

>>> del a

每天一小时python官方文档学习(四)————数据结构之列表相关推荐

  1. 每天一小时python官方文档学习(一)————python的简单介绍

    我们都知道,python的官方文档写得十分详尽,也是每一个学习python的人都绕不开的. 所以从今天开始,我每天都会用一小时学习python的官方文档,按照文档目录的顺序,摘录一些有用的语句,写下一 ...

  2. 每天一小时python官方文档学习(七)————模块与包

    6. 模块 模块是一个包含Python定义和语句的文件,实际上就是一个正常的.py文件.但是作用和普通需要运行的程序不一样,它实际上有点像函数.如果说函数实现了代码的重用,模块则是实现了函数的重用.我 ...

  3. 每天一小时python官方文档学习(六)————循环和条件控制的进阶用法

    学习完数据结构之后,我们就能够对之前在第二天中讲过的流程控制工具,添加更多的用法了,这里主要介绍的是for循环语句和if与while条件判断语句. 5.6. 循环的技巧 我们学过的遍历序列for i ...

  4. 每天一小时python官方文档学习(三)————函数

    上一天看到第四章的一半,介绍了一些常用的流程控制工具,也就是常用语句,主要是if.for.range().break.continue.else和pass.今天把第四章剩下的看完,讲的是如何在pyth ...

  5. 每天一小时python官方文档学习(五)————数据结构之元组、集合与字典

    昨天介绍完了最常用的列表,之后就是次常用的元组.集合与字典了. 5.3. 元组和序列 元组和之前讲过的列表有很多共同特性,例如索引和切片操作.实际上,他们是 序列 数据类型(list, tuple, ...

  6. 每天一小时python官方文档学习(二)————流程控制工具

    4. 其他流程控制工具 4.1. if 语句 大多数人都很熟悉的if语句: if condition1:pass elif condition2:pass else condition3:pass 注 ...

  7. Python官方文档学习心得(第三篇)

    1.定义方法 关键字 def 是方法定义的标志.接下来紧跟方法名和被圆括号所包围的参数列表.方法的主 体语句将在下一行开始并且必须缩进. 方法主体的首句可选择性地是一句字符,用来说明方法的主要功能 例 ...

  8. Python官方文档学习心得(第六篇)

    1.作用域 关键字 global 和 nonlocal会影响变量绑定,因为是全局变量 2.类 因此类可以定义一个名叫_init()的特殊方法,如下: def__init__(self): self.d ...

  9. Python官方文档学习心得(第五篇)

    1.模块 一个模块是包含 python 定义和语句的文件.文件名称是由模块名加上后缀名.py 组成的.在 模块中,模块的名字(可以作为一个字符串)是一个作为全局变量_name_的值的变量 fibo是模 ...

最新文章

  1. 聊聊storm的LoggingMetricsConsumer
  2. Oracle启用、禁用角色
  3. 用官方的SSD1306.py 驱动 OLED
  4. OpenStack nova-network 支持多vlan技术实现片段代码
  5. .net函数查询_SQL查询语句总是先执行SELECT?你们都错了!
  6. 可靠型园区网组网,用VRRP还是堆叠?
  7. 【ML】特征归一化、为什么归一化、归一化的方法、归一化方法选择依据
  8. 流量卡之家:5G手机价格没那么“邪性” 门槛降低一半
  9. Unity Recorder的使用讲解
  10. 【小程序开发原创】小程序裁剪图片上传头像,二维码源码
  11. atob解码图片base64时候报错
  12. 老生常谈之Android里的dp和sp
  13. Java:Windows 10下载和配置JDK
  14. 主成分分析(PCA)原理及推导
  15. Batch和Epoch之间的区别是什么?
  16. Cache Server缓存服务器
  17. [ Java学习 ] 包语句 package等语句的汇总整理
  18. Windows下删除卸载WPS网盘
  19. es6相关面试题:1.rest参数;2.new.target;3.object.defineProperty与Proxy的区别;4.Reflect对象作用;5.lterator迭代器;6.async
  20. mysql单表1000万条_mysql单表千万条数据测试

热门文章

  1. git stash参数介绍
  2. 微型计算机及接口技术试题,1月自考微型计算机及其接口技术试题及答案解析...
  3. java随机抽题系统_为什么要使用考试系统的随机组卷功能?
  4. 利用JS脚本快速删除百度网盘同一目录下的不需要文件(可以参考这个方法删除重复文件)
  5. GIS专业核心课程电子教材配套实验数据汇总(持续更新)
  6. WCF服务寄宿IIS时.SVC文件无法浏览的解决办法
  7. C语言试题七十一之请编写函数求出这个数的阶乘
  8. Android之升级OkHttp编译提示错误如下Using ‘body(): ResponseBody?’ is an error. moved to val
  9. Android之android.os.NewWorkOnMainThreadException解决办法
  10. Android之JSON处理器FastJson