01. Python-列表和元组

目录

1. 序列

1.1 索引

1.2 切片

1.2.1 简写

1.2.2 步长

1.3 序列相加

1.4 乘法

1.5 成员资格

2. 列表

2.1 函数list

2.2 列表的基本操作

2.3 列表方法

2.4 元组不可修改的序列


1. 序列

1.1 索引

序列中的所有元素都有编号——从0开始递增。使用负数索引时,Python将从右(即从最后一个元素)开始往左数,因此-1是最后一个元素的位置。

>>> greeting = 'Hello'
>>> greeting[0]
'H'
>>> greeting[-1]
'o'
>>> 'Hello'[1]
'e'

1.2 切片

除使用索引来访问单个元素外,还可使用切片 (slicing)来访问特定范围内的元素。为此,可使用两个索引,并用冒号分隔:

>>> tag = '<a href="http://www.python.org">Python web site</a>'
>>> tag[9:30]
'http://www.python.org'
>>> tag[32:-4]
'Python web site'

切片适用于提取序列的一部分,其中的编号非常重要:第一个索引是包含的第一个元素的编号,但第二个索引是切片后余下的第一个元素的编号。其中第一个索引指定的元素包含在切片内,但第二个索引指定的元素不包含在切片内

>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> numbers[3:6] 
[4, 5, 6]
>>> numbers[0:1] 
[1]

1.2.1 简写

>>> numbers[7:10]
[8, 9, 10]

如果要从列表末尾开始数,可使用负数索引。

>>> numbers[-3:-1]
[8, 9]
>>> numbers[-3:0]
[]
>>> numbers[-3:]
[8, 9, 10]

如果切片始于序列开头,可省略第一个索引

>>> numbers[:3]
[1, 2, 3]

要复制整个序列,可将两个索引都省略

>>> numbers[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1.2.2 步长

在普通切片中,步长为1。这意味着从一个元素移到下一个元素,因此切片包含起点和终点之间的所有元素。

>>> numbers[0:10:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

 步长为2时,将从起点和终点之间每隔一个元素提取一个元素。

>>> numbers[0:10:2]
[1, 3, 5, 7, 9]
>>> numbers[3:6:3]
[4]

要从序列中每隔3个元素提取1个,只需提供步长4即可。

>>> numbers[::4]
[1, 5, 9]

当然,步长不能为0,否则无法向前移动,但可以为负数,即从右向左提取元素。第一个索引依然包含在内,而第二个索引不包含在内。步长为负数时,第一个索引必须比第二个索引大。步长为正数时,它从起点移到终点,而步长为负数时,它从终点移到起点

>>> numbers[8:3:-1]
[9, 8, 7, 6, 5]
>>> numbers[10:0:-2]
[10, 8, 6, 4, 2]
>>> numbers[0:10:-2]
[]
>>> numbers[::-2]
[10, 8, 6, 4, 2]
>>> numbers[5::-2]
[6, 4, 2]
>>> numbers[:5:-2]
[10, 8]

1.3 序列相加

可使用加法运算符来拼接序列。从错误消息可知,不能拼接列表和字符串,虽然它们都是序列。一般而言,不能拼接不同类型的序列。

>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> 'Hello,' + 'world!'
'Hello, world!'
>>> [1, 2, 3] + 'world!'
# Traceback (innermost last):
# File "<pyshell>", line 1, in ?
#    [1, 2, 3] + 'world!'
# TypeError: can only concatenate list (not "string") to list

1.4 乘法

将序列与数x 相乘时,将重复这个序列x 次来创建一个新序列:

>>> 'python' * 5
'pythonpythonpythonpythonpython'
>>> [42] * 10
[42, 42, 42, 42, 42, 42, 42, 42, 42, 42]

None 、空列表和初始化

空列表是使用不包含任何内容的两个方括号([] )表示的。如果要创建一个可包含10个元素的列表,但没有任何有用的内容,可像前面那样使用[42]*10 。但更准确的做法是使用[0]*10 ,这将创建一个包含10个零的列表。然而,在有些情况下,你可能想使用表示“什么都没有”的值,如表示还没有在列表中添加任何内容。在这种情况下,可使用None 。在Python中,None 表示什么都没有。因此,要将列表的长度初始化为10,可像下面这样做:

>>> sequence = [None] * 10
>>> sequence
[None, None, None, None, None, None, None, None, None, None]

1.5 成员资格

要检查特定的值是否包含在序列中,可使用运算符in 。它检查是否满足指定的条件,并返回相应的值:满足时返回True ,不满足时返回False 。这样的运算符称为布尔运算符 ,而前述真值称为布尔值 。 

开头两个示例使用成员资格测试分别检查'w' 和'x' 是否包含在字符串变量permissions 中。

接下来的示例检查提供的用户名mlh是否包含在用户列表中,这在程序需要执行特定的安全策略时很有用(在这种情况下,可能还需检查密码)。最后一个示例检查字符串变量subject 是否包含字符串'$$$' ,这可用于垃圾邮件过滤器中。

>>> permissions = 'rw'
>>> 'w' in permissions
True
>>> 'x' in permissions
False
>>> users = ['mlh', 'foo', 'bar']
>>> input('Enter your user name: ') in users
Enter your user name: mlh
True
>>> subject = '$$$ Get rich now!!! $$$'
>>> '$$$' in subject
True

运算符in 检查指定的对象是否是序列(或其他集合)的成员(即其中的一个元素),但对字符串来说,只有它包含的字符才是其成员或元素,

>>> 'P' in 'Python'
True

可使用运算符in 来检查指定的字符串是否为另一个字符串的子串。

长度、最小值和最大值

函数len 返回序列包含的元素个数,而min 和max 分别返回序列中最小和最大的元素。

调用max 和min 时指定的实参并不是序列,而直接将数作为实参。

>>> numbers = [100, 34, 678]
>>> len(numbers)
3
>>> max(numbers)
678
>>> min(numbers)
34
>>> max(2, 3)
3
>>> min(9, 3, 2, 5)
2

2. 列表

列表是可变的

2.1 函数list

它实际上是一个类,而不是函数。

可将任何序列(而不仅仅是字符串)作为list 的参数。

>>> list('Hello')
['H', 'e', 'l', 'l', 'o']

2.2 列表的基本操作

 可对列表执行所有的标准序列操作,如索引、切片、拼接和相乘。

列表修改:给元素赋值、删除元素、给切片赋值以及使用列表的方法。并非所有列表方法都会修改列表。

01. 修改列表:给元素赋值

使用索引表示法给特定位置的元素赋值,如x[1] = 2 。不能给不存在的元素赋值,因此如果列表的长度为2,就不能给索引为100的元素赋值。要这样做,列表的长度至少为101

>>> x = [1, 1, 1]
>>> x[1] = 2
>>> x
[1, 2, 1]

02. 删除元素

从列表中删除元素也很容易,只需使用del 语句即可

>>> names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
>>> del names[2]
>>> names
['Alice', 'Beth', 'Dee-Dee', 'Earl']

03. 给切片赋值

>>> name = list('Perl')
>>> name
['P', 'e', 'r', 'l']
>>> name[2:] = list('ar')
>>> name
['P', 'e', 'a', 'r']

过使用切片赋值,可将切片替换为长度与其不同的序列。

>>> name = list('Perl')
>>> name[1:] = list('ython')
>>> name
['P', 'y', 't', 'h', 'o', 'n']

使用切片赋值还可在不替换原有元素的情况下插入新元素。

>>> numbers = [1, 5]
>>> numbers[1:1] = [2, 3, 4]
>>> numbers
[1, 2, 3, 4, 5]

可采取相反的措施来删除切片。与del numbers[1:4] 等效

>>> numbers
[1, 2, 3, 4, 5]
>>> numbers[1:4] = []
>>> numbers
[1, 5]

2.3 列表方法

01. append

方法append 用于将一个对象附加到列表末尾。

append就地修改列表。它不会返回修改后的新列表,而是直接修改旧列表。

>>> lst = [1, 2, 3]
>>> lst.append(4)
>>> lst
[1, 2, 3, 4]

02. clear

方法clear 就地清空列表的内容

>>> lst = [1, 2, 3]
>>> lst.clear()
>>> lst
[]
# 类似于切片赋值语句lst[:] = []

03. copy

方法copy 复制列表。常规复制只是将另一个名称关联到列表。

>>> a = [1, 2, 3]
>>> b = a
>>> b[1] = 4
>>> a
[1, 4, 3]

要让a和b指向不同的列表,就必须将b关联到a的副本

>>> a = [1, 2, 3]
>>> b = a.copy()
>>> b[1] = 4
>>> a
[1, 2, 3]
# 这类似于使用a[:] 或list(a) ,它们也都复制a

04. count

方法count 计算指定的元素在列表中出现了多少次。

>>> ['to', 'be', 'or', 'not', 'to', 'be'].count('to')
2
>>> x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
>>> x.count(1)
2
>>> x.count([1, 2])
1

05. extend

方法extend 让你能够同时将多个值附加到列表末尾,为此可将这些值组成的序列作为参数提供给方法extend 。换而言之,你可使用一个列表来扩展另一个列表。

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]

这可能看起来类似于拼接,但存在一个重要差别,那就是将修改被扩展的序列(这里是a )。在常规拼接中,情况是返回一个全新的序列。

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a + b
[1, 2, 3, 4, 5, 6]
>>> a

a = a + b,效率比extend低

06. index

方法index 在列表中查找指定值第一次出现的索引。指定值不存在会报错。

>>> knights = ['We', 'are', 'the', 'knights', 'who', 'say', 'ni']
>>> knights.index('who')
4

07. insert

方法insert 用于将一个对象插入列表。

>>> numbers = [1, 2, 3, 5, 6, 7]
>>> numbers.insert(3, 'four')
>>> numbers
[1, 2, 3, 'four', 5, 6, 7]

08. pop

方法pop 从列表中删除一个元素(末尾为最后一个元素),并返回这一元素。

>>> x = [1, 2, 3]
>>> x.pop()
3
>>> x
[1, 2]
>>> x.pop(0)
1
>>> x
[2]

pop 是唯一既修改列表又返回一个非None 值的列表方法。

使用pop 可实现一种常见的数据结构——栈 (stack)。后进先出 (LIFO)

ush 和pop 是大家普遍接受的两种栈操作(加入和取走)的名称。Python没有提供push ,但可使用append 来替代。方法pop 和append 的效果相反,因此将刚弹出的值压入(或附加)后,得到的栈将与原来相同。

>>> x = [1, 2, 3]
>>> x.append(x.pop())
>>> x
[1, 2, 3]

要创建先进先出(FIFO)的队列,可使用insert(0, ...) 代替append 。另外,也可继续使用append ,但用pop(0) 替代pop() 。一种更佳的解决方案是,使用模块collections 中的deque 。

09. remove

方法remove 用于删除第一个为指定值的元素。

删除不存在的元素会报错。

remove 是就地修改且不返回值的方法之一。不同于pop 的是,它修改列表,但不返回任何值。

>>> x = ['to', 'be', 'or', 'not', 'to', 'be']
>>> x.remove('be')
>>> x
['to', 'or', 'not', 'to', 'be']

10. reverse

方法reverse 按相反的顺序排列列表中的元素

reverse 修改列表,但不返回任何值

>>> x = [1, 2, 3]
>>> x.reverse()
>>> x
[3, 2, 1]

如果要按相反的顺序迭代序列,可使用函数reversed 。这个函数不返回列表,而是返回一个迭代器。可使用list 将返回的对象转换为列表。

>>> x = [1, 2, 3]
>>> list(reversed(x))
[3, 2, 1]

11. sort

方法sort 用于对列表就地排序。就地排序意味着对原来的列表进行修改,使其元素按顺序排列,而不是返回排序后的列表的副本。

>>> x = [4, 6, 2, 1, 7, 9]
>>> x.sort()
>>> x
[1, 2, 4, 6, 7, 9]
>>> x = [4, 6, 2, 1, 7, 9]
>>> y = x.sort() # Don't do this!
>>> print(y)
None

sort 修改x 且不返回任何值,最终的结果是x 是经过排序的,而y 包含None 。正确的方式之一是先将y 关联到x 的副本,再对y 进行排序

>>> x = [4, 6, 2, 1, 7, 9]
>>> y = x.copy()
>>> y.sort()
>>> x
[4, 6, 2, 1, 7, 9]
>>> y
[1, 2, 4, 6, 7, 9]

只是将x 赋给y 是不可行的,因为这样x 和y 将指向同一个列表。为获取排序后的列表的副本,另一种方式是使用函数sorted 。

>>> x = [4, 6, 2, 1, 7, 9]
>>> y = sorted(x)
>>> x
[4, 6, 2, 1, 7, 9]
>>> y
[1, 2, 4, 6, 7, 9]

这个函数可用于任何序列,但总是返回一个列表

>>> sorted('Python')
['P', 'h', 'n', 'o', 't', 'y']

如果要将元素按相反的顺序排列,可先使用sort (或sorted ),再调用方法reverse ,也可使用参数reverse

12. 高级排序

方法sort 接受两个可选参数:key 和reverse 。这两个参数通常是按名称指定的,称为关键字参数,参数key 类似于参数cmp :你将其设置为一个用于排序的函数。然而,不会直接使用这个函数来判断一个元素是否比另一个元素小,而是使用它来为每个元素创建一个键,再根据这些键对元素进行排序。因此,要根据长度对元素进行排序,可将参数key 设置为函数len 。

>>> x = ['aardvark', 'abalone', 'acme', 'add', 'aerate']
>>> x.sort(key=len)
>>> x
['add', 'acme', 'aerate', 'abalone', 'aardvark']

对于另一个关键字参数reverse ,只需将其指定为一个真值(True 或False ),以指出是否要按相反的顺序对列表进行排序。

>>> x = [4, 6, 2, 1, 7, 9]
>>> x.sort(reverse=True)
>>> x
[9, 7, 6, 4, 2, 1]
>>> x.sort(reverse=False)
>>> x
[1, 2, 4, 6, 7, 9]

函数sorted 也接受参数key 和reverse 。

2.4 元组不可修改的序列

与列表一样,元组也是序列,唯一的差别在于元组是不能修改的。

# 创建元组
>>> 1, 2, 3
(1, 2, 3)
# 元组还可用圆括号括起
>>> (1, 2, 3)
(1, 2, 3)
# 空元组用两个不包含任何内容的圆括号表示
>>> ()
()

虽然只有一个值,也必须在它后面加上逗号

逗号至关重要,仅将值用圆括号括起不管用:(42) 与42 完全等效。

>>> 42
42
>>> (42)
42
>>> 42,
(42,)
>>> (42,)
(42,)
>>> 3 * (40 +  2)
126
>>> 3 * (40 + 2,)
(42, 42, 42)

函数tuple 的工作原理与list 很像:它将一个序列作为参数,并将其转换为元组。如果参数已经是元组,就原封不动地返回它。

>>> tuple([1, 2, 3])
(1, 2, 3)
>>> tuple('abc')
('a', 'b', 'c')
>>> tuple((1, 2, 3))
(1, 2, 3)

元组并不太复杂,而且除创建和访问其元素外,可对元组执行的操作不多。元组的创建及其元素的访问方式与其他序列相同。

>>> x = 1, 2, 3
>>> x[1]
2
>>> x[0:2]
(1, 2)

元组的切片也是元组,就像列表的切片也是列表一样。

它们用作映射中的键(以及集合的成员),而列表不行。

有些内置函数和方法返回元组,这意味着必须跟它们打交道。只要不尝试修改元组,与元组“打交道”通常意味着像处理列表一样处理它们(需要使用元组没有的index 和count 等方法时例外)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南河Aure

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值