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

终于进入到第五章数据结构部分了,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
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值