python中j real,RealPython 基础教程:Python 中的列表和元组

列表(list)和元组(tuple)几乎可称得上是 Python 中最常用、最有用的数据类型了。在每个非简单的 Python 中,你都能发现它们的使用之处。

本文将介绍 list 和 tuple 的重要特性。你将学会如何定义和使用它们,并掌握何时以及如何在 Python 程序中使用这些类型的对象。

【Python 中的列表(list)】

简言之,list 是一个包含任意对象的集合,有点像其他编程语言中的数组,但是更加灵活。

在 Python 中,使用中括号([])来定义一个包含一系列对象的 list,list 中的对象之间用逗号(,)隔开。

就像下边这样:

>>> a = ['foo', 'bar', 'baz', 'qux']

>>> a

['foo', 'bar', 'baz', 'qux']

>>> type(a)

list 的重要特性包括:

list 是有序的

list 可以包含任意种类和数目的对象

list 支持使用索引来访问其中的元素

list 支持任意深度的嵌套

list 是可变的

list 是动态的

我们下边逐一详细介绍这些特性。

1,list 是有序的

list 不仅仅是对象的集合,它是这些对象的有序集合。定义 list 时为其中元素指定的顺序,是 list 的一个固有特征,并在 list 的整个生命周期中保持不变。

两个拥有相同元素但元素顺序不同的 list 是不相同的。

>>> a = ['foo', 'bar', 'baz', 'qux']

>>> b = ['baz', 'qux', 'bar', 'foo']

>>> a == b

False

>>> a is b

False

>>>

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

False

2,list 可以包含任意对象

list 可以包含各种各样的对象。

list 中的元素可以是相同类型的,也可以是不同类型的。

>>> a = [2, 4, 6, 8]

>>> a

[2, 4, 6, 8]

>>> a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]

>>> a

[21.42, 'foobar', 3, 4, 'bark', False, 3.14159]

list 中也可以包含复杂的对象,比如函数、类以及模块。

>>> int

>>> len

function len>

in

>>> def foo():

... pass

...

>>> foo

>

0x000001D893CFFDC8

>>> import math

>>> math

>>>

>>> a = [int, len, foo, math]

>>> a

[, function len>, at 0x000001D893CFFDC8>,

in

foo

math' (built-in)>]

list 可以包含任意数目的对象,从 0 个一直多到内存允许的最大值。

>>> a = []

>>> a

[]

>>> len(a)

0

>>> a = ['foo']

>>> a

['foo']

>>> len(a)

1

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,]

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

>>> len(a)

21

list 中的对象不必是唯一的,一个对象可以在 list 中出现多次。

>>> a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']

>>> a

['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']

3,可通过索引访问 list 中的元素

list 中的单个元素可使用方括号通过元素索引来访问,这和访问字符串中的单个字符的方法非常相似。list 元素索引也是以 0 为基础的。

考虑下边这个 list:

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

这个 list 中元素的索引如下所示:

8e0e964c7e7a8f4fae334a1aae9ac448.png

下边是访问 list 元素的 Python 代码:

>>> a[0]

'foo'

>>> a[2]

'baz'

>>> a[5]

'corge'

实际上,所有字符串索引相关操作基本上都适用于 list。比如,list 负值索引是从 list 尾部进行计数的。

911fbfc03104770693efba80dd6d0617.png

>>> a[-1]

'corge'

>>> a[-2]

'quux'

>>> a[-5]

'bar'

切片操作同样适用于 list。

假如 a 是一个 list 对象,表达式 a[m:n] 返回一个 a 的子 list,起始于索引 m,终止于索引 n,但不包含索引为 n 的元素。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2:5]

['baz', 'qux', 'quux']

其他适用于字符串的切片特性也适用于 list 切片操作。

可使用正值或负值索引>>> a[-5:-2]

['bar', 'baz', 'qux']

>>> a[1:4]

['bar', 'baz', 'qux']

>>> a[-5:-2] == a[1:4]

True若忽略第一个索引,则切片起始于 list 的开头元素;若忽略第二个索引,则切片延伸至 list 的末尾元素>>> print(a[:4], a[0:4])

['foo', 'bar', 'baz', 'qux'] ['foo', 'bar', 'baz', 'qux']

>>> print(a[2:], a[2:len(a)])

['baz', 'qux', 'quux', 'corge'] ['baz', 'qux', 'quux', 'corge']

>>>

>>> a[:4] + a[4:]

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[:4] + a[4:] == a

True可指定切片的步长,步长可为正值或负值>>> a[0:6:2]

['foo', 'baz', 'quux']

>>> a[1:6:2]

['bar', 'qux', 'corge']

>>> a[6:0:-2]

['corge', 'qux', 'bar']反转 list 的方法和反转字符串的方法相同>>> a[::-1]

['corge', 'quux', 'qux', 'baz', 'bar', 'foo'][:] 语法适用于 list,但是这个操作在 list 和字符串的实现上有个重要的区别。若 s 是一个字符串,s[:] 返回的是对字符串 s 的引用:>>> s = 'foobar'

>>> s[:]

'foobar'

>>> s[:] is s

True

若 a 是一个 list,a[:] 返回的是对 list a 的一份拷贝:

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[:]

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[:] is a

False

Python 的一些运算符和内置函数可用于操作 list,使用方法和操作字符串类似。

in 和 not in 运算符>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> 'qux' in a

True

>>> 'thud' not in a

True连接(+)和复制(*)运算符>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a + ['grault', 'garply']

['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']

>>> a * 2

['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']len()、min() 和 max() 函数

>>> a['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> len(a)

6

>>> min(a)

'bar'

>>> max(a)

'qux'

看起来,list 和字符串行为很相似。这并不是偶然的。它们都是一个更一般的对象类型 iterable 的特例。我们会在后续的学习中了解如何定义一个 iterable。

在我们上边的例子中,list 对象在使用之前总是先被赋值给一个变量,我们也可以直接在 list 常量上执行各种操作。

>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]

'baz'

>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]

['corge', 'quux', 'qux', 'baz', 'bar', 'foo']

>>> 'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

True

>>> ['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])

6

4,list 可以嵌套

我们知道,list 中可以包含任意种类的对象,这其中就包括 list 类型的对象。

list 可以包含子 list,子 list 中还可以包含自己的子 list,如此这般,可以嵌套至任意深度。

看下边这个例子:

>>> x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']

>>> x

['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']

x 指向的对象的结构可用下图表示:

d9873c43341b417b7db34790e438ca4e.png

x[0]、x[2] 和 x[4] 都是长度为 1 的字符串:

>>> print(x[0], x[2], x[4])

a g j

x[1] 和 x[3] 是 x 的子 list:

>>> x[1]

['bb', ['ccc', 'ddd'], 'ee', 'ff']

>>> x[3]

['hh', 'ii']

子 list 中的元素也可以通过索引语法来访问,只需要追加额外的 [] 包含的索引即可。

>>> x[1]

['bb', ['ccc', 'ddd'], 'ee', 'ff']

>>> x[1][0]

'bb'

>>> x[1][1]

['ccc', 'ddd']

>>> x[1][2]

'ee'

>>> x[1][3]

'ff'

>>>

>>> x[3]

['hh', 'ii']

>>> print(x[3][0], x[3][1])

hh ii

可以看到,x[1][1] 又是一个子 list,再增加一个索引就可以访问其中的元素:

>>> x[1][1]

['ccc', 'ddd']

>>> print(x[1][1][0], x[1][1][1])

ccc ddd

你可以定义任意嵌套深度的 list,当然,嵌套越深,访问起来也越复杂。

常见的索引和切片操作同样适用于子 list。

>>> x[1][1][-1]

'ddd'

>>> x[1][1:3]

[['ccc', 'ddd'], 'ee']

>>> x[3][::-1]

['ii', 'hh']

需要注意的是,list 上的运算符和函数操作仅作用在你指定的层级,它们不会递归应用在子 list 上。

我们以 len() 和 in 为例,看一下存在子 list 时的操作结果。

>>> x

['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']

>>> len(x)

5

>>>

>>> 'ddd' in x

False

>>> 'ddd' in x[1]

False

>>> 'ddd' in x[1][1]

True

len(x) 只返回 x 第一级的元素个数,不会包含子 list 中元素的数目;in 同样只判断 'ddd' 是否存在于右操作数所在的那一层级,不会在子 list 中递归查找。

5,list 是可变的

我们前边介绍的大部分数据类型都是原子类型。比如,整数或浮点数对象都是不可再分割的原始单元。这些类型是不可变的,意味着对象一旦被赋值就无法再次改变其内容。在 Python 中考虑改变一个整数的值没多大意义,如果你想要一个其他值的整数,再创建一个整数对象并为其赋值就行了。

和整数、浮点数有点不一样,字符串是一个复合类型。字符串可以被分拆为更小的部分:单个字符。看起来,修改字符串中某个字符的值是有意义的。但事实是,你无法改变字符串中单个字符的值。Python 中的字符串也是不可变的。

list 是我们遇到的第一个可变数据类型。list 对象创建之后,我们可向其中随意地添加、删除、变换和移动元素。Python 提供了很多方式用来修改 list。

5.1 修改 list 中单个元素的值

list 中单个元素的值可通过索引与简单赋值来替换。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2] = 10

>>> a[-1] = 20

>>> a

['foo', 'bar', 10, 'qux', 'quux', 20]

而字符串中的单个字符却无法被替换。

>>> s = 'foobarbaz'

>>> s[2] = 'x'

Traceback (most recent call last):

File "

", line 1, in

TypeError: 'str' object does not support item assignment

可通过 del 命令删除 list 中的元素。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> del a[3]

>>> a

['foo', 'bar', 'baz', 'quux', 'corge']

5.2 修改 list 中多个元素的值

Python 支持通过切片赋值语法来同时修改 list 中的多个连续元素。

a[m:n] =

我们暂时可将此处的 iterable 当做是一个 list。这个赋值操作会将 a 中的 [m:n] 片段整体替换为 iterable。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[1:4]

['bar', 'baz', 'qux']

>>> a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]

>>> a

['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']

>>> a[1:6]

[1.1, 2.2, 3.3, 4.4, 5.5]

>>> a[1:6] = ['Bark!']

>>> a

['foo', 'Bark!', 'quux', 'corge']

iterable 中元素的个数不需要和 a[m:n] 片段中元素的个数相等。Python 会根据需要自动伸缩 list。

我们可以用多个元素来替换 list 中的一个元素,只需要将 [m:n] 切片指定为需要替换的单元素片段即可。

a = [1, 2, 3]

>>> a[1:2] = [2.1, 2.2, 2.3]

>>> a

[1, 2.1, 2.2, 2.3, 3]

注意,这和将 list 单个元素替换为另一个 list 对象不同!

a = [1, 2, 3]

>>> a[1] = [2.1, 2.2, 2.3]

>>> a

[1, [2.1, 2.2, 2.3], 3]

我们也可以在 list 上执行纯粹的插入操作:插入元素而不移除其他元素。这可通过将切片索引范围设置为插入位置的索引且长度为0即可:[n:n],n 为插入位置索引。

>>> a = [1, 2, 7, 8]

>>> a[2:2] = [3, 4, 5, 6]

>>> a

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

有两种方法可用来删除 list 中的多个连续元素。

给要删除的切片赋值为一个空的 list:

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[1:5] = []

>>> a

['foo', 'corge']

通过 del 命令删除 list 切片:

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> del a[1:5]

>>> a

['foo', 'corge']

5.3 向 list 中前插或追加元素

可通过连接(+)或增量赋值(+=)运算符向 list 中前插或追加元素。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a += ['grault', 'garply']

>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']

>>>

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a = [10, 20] + a

>>> a

[10, 20, 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']

注意,用于和 list 执行连接操作的对象也必须是 list 类型。因此,如果想在 list 中添加一个元素,你需要通过单例 list (只含有一个元素)的方式来包装这个元素。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a += 20

Traceback (most recent call last):

File "

", line 1, in

TypeError: 'int' object is not iterable

>>>

>>> a += [20]

>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 20]

补充说明一点。

技术上讲,必须用另一个 list 和源 list 做连接,这个说法并不太正确。更精确的说法是,和源 list执行连接操作的对象必须是一个 iterable。当然,list 本身就是 iterable,因此 list 可被用于和另一个 list 对象进行连接。

字符串也是 iterable。但是,请看一下将字符串连接到 list 对象上时会发生什么。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']

>>> a += 'corge'

>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'c', 'o', 'r', 'g', 'e']

结果可能和你想象的不太一样。

当字符串被迭代遍历时,其结果是一个字符组成的 list。

在上边这个例子中,连接到 list a 的对象也是一个 list:[ 'c', 'o', 'r', 'g', 'e']。

如果你真要往 list 尾部添加一个字符串对象,你需要将这个字符串包装到一个单例 list 中。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']

>>> a += ['corge']

>>> a

['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

5.4 用于修改 list 的方法

Python 提供了一些内置的方法用于修改 list。

下面介绍这些方法,假如 a 是一个 list 对象。

a.append():在 list 尾部追加一个对象。

>>> a = ['a', 'b']

>>> a.append(123)

>>> a

['a', 'b', 123]

请记住:list 方法原地操作目标 list 对象,这些方法不会返回新的 list 对象。

>>> a = ['a', 'b']

>>> x = a.append(123)

>>> print(x)

None

>>> a

['a', 'b', 123]

我们在上边的 list 连接操作时提到,通过连接(+)运算符将 iterable 连接到 list 对象时,iterable 中的元素会被打散,并逐个连接到 list 中。

>>> a = ['a', 'b']

>>> a + [1, 2, 3]

['a', 'b', 1, 2, 3]

>>> [1, 2, 3] + a

[1, 2, 3, 'a', 'b']

a.append() 方法并非如此工作。如果一个 iterable 通过 a.append() 被追加到 list a 中,这个 iterable 会被视为一个单独的对象。

>>> a = ['a', 'b']

>>> a.append([1, 2, 3])

>>> a

['a', 'b', [1, 2, 3]]

因此,可以使用 append() 方法将字符串作为一个单独的实体追加到 list 中。

>>> a = ['a', 'b']

>>> a.append('foo')

>>> a

['a', 'b', 'foo']

a.extend():使用 iterable 中的元素来扩展 list 对象。

这个方法同样用于在 list 尾部追加元素,和 a.append() 不同的是,它将 iterable 中的元素逐个追加到 list 尾部,这和连接(+)运算符相似,确切的说,它和增量(+=)运算符行为是一致的。

>>> a = ['a', 'b']

>>> a.extend([1, 2, 3])

>>> a

['a', 'b', 1, 2, 3]

>>>

>>> a = ['a', 'b']

>>> a += [1, 2, 3]

>>> a

['a', 'b', 1, 2, 3]

a.insert():向 list 中插入一个对象。

a.insert() 将对象 obj 插入到 list a 的 index 指定的位置。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a.insert(3, 3.14159)

>>> a[3]

3.14159

>>> a

['foo', 'bar', 'baz', 3.14159, 'qux', 'quux', 'corge']

a.remove():从 list 中移除一个对象。

将对象 obj 从 list a 中删除。若 a 中存在多个值和 obj 相等的对象,每次只删除一个;若 a 中不存在 obj,将触发异常。

>>> a = ['foo', 'bar', 'baz', 'qux', 'bar', 'quux', 'corge']

>>> a.remove('bar')

>>> a

['foo', 'baz', 'qux', 'bar', 'quux', 'corge']

>>> a.remove('babala')

Traceback (most recent call last):

File "

", line 1, in

ValueError: list.remove(x): x not in list

a.pop(index = -1):从 list 中移除一个元素。

这个方法和 a.remove() 有两点不同:

传入的参数为待删除对象的索引,而不是对象本身

该方法会返回被删除的对象

若未指定参数 index 的值,默认删除 list 的尾元素。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a.pop()

'corge'

>>> a

['foo', 'bar', 'baz', 'qux', 'quux']

>>>

>>> a.pop()

'quux'

>>> a

['foo', 'bar', 'baz', 'qux']

若指定了 index 的值,位于 index 的元素会被删除并被返回。

index 可以是负值。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a.pop(1)

'bar'

>>> a

['foo', 'baz', 'qux', 'quux', 'corge']

>>>

>>> a.pop(-3)

'qux'

>>> a

['foo', 'baz', 'quux', 'corge']

index 默认为 -1,因此,a.pop(-1) 等同于 a.pop()。

6,list 是动态的

从上边几个特性的讲解中,我们已经可以认识到,list 是随着各种操作而动态变化的,它会自行伸缩。

>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

>>> a[2:2] = [1, 2, 3]

>>> a += [3.14159]

>>> a

['foo', 'bar', 1, 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]

>>>

>>> a[2:3] = []

>>> del a[0]

>>> a

['bar', 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]

【Python 中的元组(tuple)】

tuple 是 Python 提供的另一个有序对象集合数据类型。

1,定义和使用 tuple

tuple 在各方面和 list 都是相同的,除了下边这两个属性:

Python 使用圆括号(())来定义 tuple 对象

tuple 对象是不可变的

下边给出一个简短的例子来展示 tuple 的定义、索引和切片。

>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')

>>> t

('foo', 'bar', 'baz', 'qux', 'quux', 'corge')

>>>

>>> t[0]

'foo'

>>> t[-1]

'corge'

>>> t[1::2]

('bar', 'qux', 'corge')

通过切片来反转字符串和 list 的操作也适用于 tuple。

>>> t[::-1]

('corge', 'quux', 'qux', 'baz', 'bar', 'foo')

如同 list,tuple 对象也是有序的,可包含任意对象,可通过索引访问,可进行切片操作,也可以嵌套定义。

tuple 和 list 最大的不同在于:tuple 对象不能被修改!

>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')

>>> t[2] = 'Bark!'

Traceback (most recent call last):

File ", line 1, in "

TypeError: 'tuple' object does not support item assignment

那么,为什么要使用 tuple 而非 list 呢?

在包含相同的元素的情况下,操作一个 tuple 要比 list 快些,这个速度上的差别可能在元素很多时比较显著。

有时候,处于业务上的需要,我们不希望数据被修改。这时候,tuple 从语法层面为我们提供了保障。

Python 有一个数据类型为字典(dict,后续会介绍到),它的部分组件要求其值是不可变的。tuple 可满足此需求,而 list 不能。

Python 解释器命令行中可以同时输入并显示若干变量,观察输出结果,你会发现,这组变量被隐式解释为一个 tuple 对象了。

>>> a = 'foo'

>>> b = 42

>>> a, 3.14159, b

('foo', 3.14159, 42)

当定义一个 tuple 对象时,有一点需要注意。

如果你定义的是一个空的或者包含两个或更多个元素的 tuple 时,Python 会清楚地明白你的意图,正确创建一个 tuple 对象。

>>> t = ()

>>> type(t)

>>>

>>> t = (1, 2)

>>> type(t)

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

>>> type(t)

但是,如果定义只包含一个元素的 tuple 对象呢?

>>> t = (2)

>>> type(t)

>>>

>>> t = ('hello')

>>> type(t)

出现这种结果的原因是,在 Python 中圆括号也被用于定义表达式中各运算符的优先级。(2) 和 ('hello') 均被视为一个表达式,Python 计算其值,分别创建了一个整数对象和一个字符串对象。

如果你真想定义一个只包含一个元素的 tuple,不要忘了在元素之后追加一个逗号(,)。

>>> t = (2,)

>>> type(t)

>>> t[0]

2

当你在 Python 解释器命令行中输出一个单例 tuple 时,Python 解释器也会显示元素后边的逗号,以提示这是一个 tuple 对象。

>>> print(t)

(2,)

2,tuple 的赋值、打包(pack) 和 解包(unpack)

我们已经知道,一个包含若干元素的 tuple 字面量可以被赋值给一个对象。

>>> t = ('foo', 'bar', 'baz', 'qux')

这个赋值操作好比将 tuple 中的这些元素打包到一个对象中。

938a5fd0a04ce86b71a674ee694bfc84.png

>>> t

('foo', 'bar', 'baz', 'qux')

>>> t[0]

'foo'

>>> t[-1]

'qux'

如果这个打包的对象后续被赋值给一个新的 tuple,这些元素会被逐个解包到新 tuple 中的对象中。

e8e2d1998e11f1f89b1ffd4f7ffdf9d1.png

>>> (s1, s2, s3, s4) = t

'foo'

>>> s2

'bar'

>>> s3

'baz'

>>> s4

'qux'

使用解包语法时,左侧变量的个数必须和右侧 tuple 中元素的个数匹配。

>>> (s1, s2, s3) = t

Traceback (most recent call last):

File ", line 1, in "

ValueError: too many values to unpack (expected 3)

>>>

>>> (s1, s2, s3, s4, s5) = t

Traceback (most recent call last):

File ", line 1, in "

ValueError: not enough values to unpack (expected 5, got 4)

打包和解包可以在一个语句中组合使用,从而产生一个复合赋值操作。

>>> (s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')

>>> s1

'foo'

>>> s2

'bar'

>>> s3

'baz'

>>> s4

'qux'

在这种情形的赋值和少数其他的使用场景中,Python 允许省略通常用于表示 tuple 的圆括号。

>>> t = 1, 2, 3

(1, 2, 3)

>>>

>>> x1, x2, x3 = t

>>> x1

1

>>> x2

2

>>> x3

3

>>>

>>> x1, x2, x3 = 4, 5, 6

>>> x1, x2, x3

(4, 5, 6)

>>>

>>> t = 2,

>>> t

(2,)

有无圆括号都可以正常工作,但为便于理解,尽量还是使用圆括号。

tuple 赋值操作可以产生一些有点奇怪却更地道的 Python 代码。

我们在编程中经常需要交换两个变量的值。在大多数编程语言中,你需要将一个变量存储到一个临时变量中。用代码表示为:

>>> b = 'bar'

>>> a,b

('foo', 'bar')

>>> tmp = a

>>> a = b

>>> b = tmp

>>> a,b

('bar', 'foo')

在 Python 中,我们可以使用一条语句完成交换操作。

>>> a = 'foo'

>>> b = 'bar'

>>> a, b

('foo', 'bar')

>>> a,b = b,a

>>> a,b

('bar', 'foo')

相比使用临时变量,这的确是一个更现代的技术进步。

【结语】

本文详细介绍了 list 和 tuple 的基本属性和使用方法,你将会在 Python 程序中大量使用这两个数据结构。

接下来,我们会学习 Python 中另一个重要的数据类型:字典(dict)。

7e46151c976d4268e1b7bef9d7647530.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值