ZetCode

Python 列表

最后修改于 2024 年 1 月 29 日

在本文中,我们将介绍如何在 Python 中处理列表集合。

Python 列表定义

列表是值的有序集合。它可以包含各种类型的值。列表是可变容器。这意味着我们可以添加值、删除值或修改现有值。

Python 列表代表有限序列的数学概念。列表的值称为列表的项或元素。列表可以多次包含相同的值。每次出现都被视为一个独立的项。

Python 简单列表

列表元素可以通过其索引进行访问。第一个元素的索引为 0,最后一个元素的索引为 -1。

simple.py
#!/usr/bin/python

# simple.py

nums = [1, 2, 3, 4, 5]

print(nums[0])
print(nums[-1])
print(nums)

这是一个包含五个元素的简单列表。列表用方括号[]分隔。列表的元素用逗号分隔。列表的内容会打印到控制台。

nums = [1, 2, 3, 4, 5]

赋值的右侧是 Python 列表字面量。它创建一个包含五个元素的列表。

$ ./simple.py
1
5
[1, 2, 3, 4, 5]

列表可以包含各种数据类型的元素。

various_types.py
#!/usr/bin/python

# various_types.py

class Being:
    pass

objects = [1, -2, 3.4, None, False, [1, 2], "Python", (2, 3), Being(), {}]
print(objects)

在这个示例中,我们创建了一个对象列表。它包含数字、布尔值、另一个列表、字符串、元组、自定义对象和字典。

$ ./various_types.py
[1, -2, 3.4, None, False, [1, 2], 'Python', (2, 3),
    <__main__.Being instance at 0x7f653577f6c8>, {}]

Python 列表初始化

有时我们需要提前初始化一个列表,使其具有特定数量的元素。

initialization.py
#!/usr/bin/python

n1 = [0 for i in range(15)]
n2 = [0] * 15

print(n1)
print(n2)

n1[0:10] = [10] * 10

print(n1)

在此示例中,我们使用列表推导式和 * 运算符初始化了两个列表。

n1 = [0 for i in range(15)]
n2 = [0] * 15

这两个列表都初始化为十五个零。

n1[0:10] = [10] * 10

前十个值被替换为 10。

$ ./initialization.py
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0]

Python 列表函数

list函数从可迭代对象创建列表。可迭代对象可以是序列、支持迭代的容器或迭代器对象。如果未指定参数,则会创建一个新的空列表。

list_fun.py
#!/usr/bin/python

# list_fun.py

a = []
b = list()

print(a == b)

print(list((1, 2, 3)))
print(list("ZetCode"))
print(list(['Ruby', 'Python', 'Perl']))

在这个示例中,我们创建了一个空列表,一个由元组组成的列表,一个字符串列表,以及另一个列表。

a = []
b = list()

这是创建空列表的两种方法。

print(a == b)

该行打印 `True`。这证实 `a` 和 `b` 是相等的。

print(list((1, 2, 3)))

我们从 Python 元组创建了一个列表。

print(list("ZetCode"))

此行从字符串生成列表。

print(list(['Ruby', 'Python', 'Perl']))

最后,我们复制了字符串列表。

$ ./list_fun.py
True
[1, 2, 3]
['Z', 'e', 't', 'C', 'o', 'd', 'e']
['Ruby', 'Python', 'Perl']

Python 列表操作

以下代码显示了一些基本的列表操作。

list_oper.py
#!/usr/bin/python

# list_oper.py

n1 = [1, 2, 3, 4, 5]
n2 = [3, 4, 5, 6, 7]

print(n1 == n2)
print(n1 + n2)

print(n1 * 3)

print(2 in n1)
print(2 in n2)

我们定义了两个整数列表。我们在这些列表上使用了一些运算符。

print(n1 == n2)

列表的内容使用 `==` 运算符进行比较。由于元素不同,该行打印 `False`。

print(n1 + n2)

将 `n1` 和 `n2` 列表相加形成一个新列表。新列表包含两个列表的所有元素。

print(n1 * 3)

我们将乘法运算符用于列表。它将元素重复 n 次;在我们的例子中是三次。

print(2 in n1)

我们使用 `in` 运算符来查找值是否存在于列表中。它返回一个布尔值 `True` 或 `False`。

$ ./lists.py
False
[1, 2, 3, 4, 5, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
True
False

Python 序列函数

序列函数可用于任何序列类型,包括列表。

sequence_funs.py
#!/usr/bin/python

# sequence_funs.py

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

print("There are {0} items".format(len(n)))
print("Maximum is {0}".format(max(n)))
print("Minimum is {0}".format(min(n)))
print("The sum of values is {0}".format(sum(n)))

在上面的示例中,我们有四个函数:`len`、`max`、`min` 和 `sum`。

print("There are {0} items".format(len(n)))

`len` 函数返回列表的大小。即列表中的元素数量。

print("Maximum is {0}".format(max(n)))
print("Minimum is {0}".format(min(n)))

`max` 和 `min` 函数返回列表的最大值和最小值。

print("The sum of values is {0}".format(sum(n)))

`sum` 函数计算 `n` 列表中数字的总和。

$ ./sequence_funs.py
There are 8 items
Maximum is 8
Minimum is 1
The sum of values is 36

Python 添加列表元素

本节将介绍如何将元素添加到 Python 列表中。

adding.py
#!/usr/bin/python

# adding.py

langs = []

langs.append("Python")
langs.append("Perl")
print(langs)

langs.insert(0, "PHP")
langs.insert(2, "Lua")
print(langs)

langs.extend(("JavaScript", "ActionScript"))
print(langs)

我们有三种向列表添加新元素的方法:`append`、`insert` 和 `extend`。

langs = []

创建了一个空列表。

langs.append("Python")
langs.append("Perl")

`append` 方法将一个项添加到列表的末尾;我们添加了两个字符串。

langs.insert(0, "PHP")
langs.insert(2, "Lua")

`insert` 方法将元素放置在由索引号指示的特定位置。`"PHP"` 字符串插入到第一个位置,`"Lua"` 字符串插入到第三个位置。请注意,列表索引号从零开始。

langs.extend(("JavaScript", "ActionScript"))

`extend` 方法将一系列值添加到列表的末尾。在我们的例子中,Python 元组中的两个字符串被追加到我们的列表末尾。

$ ./adding.py
['Python', 'Perl']
['PHP', 'Python', 'Lua', 'Perl']
['PHP', 'Python', 'Lua', 'Perl', 'JavaScript', 'ActionScript']

Python 列表 IndexError

当列表下标超出范围时,会引发 `IndexError`。

index_error.py
#!/usr/bin/python

# index_error.py

n = [1, 2, 3, 4, 5]

try:

    n[0] = 10
    n[6] = 60

except IndexError as e:

    print(e)

在脚本中,我们定义了一个包含五个整数的列表。这些元素的索引为 0、1、2、3 和 4。使用更大的索引会导致错误。

n[6] = 60

索引 6 超出了我们列表的范围。会引发 `IndexError`。

except IndexError as e:

    print(e)

我们使用 `except` 子句捕获错误。在子句体中,我们打印错误消息。

$ ./index_error.py
list assignment index out of range

Python 列表 TypeError

如果元组的索引不是纯整数,则会引发 `TypeError`。

type_error.py
#!/usr/bin/python

# type_error.py

n = [1, 2, 3, 4, 5]

try:
    print(n[1])
    print(n['2'])

except TypeError as e:

    print("Error in file {0}".format( __file__))
    print("Message: {0}".format(e))

此示例引发 `TypeError`。

print(n['2'])

列表索引必须是整数。其他类型会导致错误。

except TypeError as e:

    print("Error in file {0}".format( __file__))
    print("Message: {0}".format(e))

在 except 块中,我们打印了发生异常的文件名和消息字符串。

$ ./typeerror.py
2
Error in file ./typeerror.py
Message: list indices must be integers, not str

Python 删除列表元素

之前我们向列表中添加了项。现在我们将从列表中删除它们。

removing.py
#!/usr/bin/python

# removing.py

langs = ["Python", "Ruby", "Perl", "Lua", "JavaScript"]
print(langs)

lang = langs.pop(3)
print("{0} was removed".format(lang))

lang = langs.pop()
print("{0} was removed".format(lang))

print(langs)

langs.remove("Ruby")
print(langs)

`pop` 方法移除并返回指定索引的元素,如果未给出索引号,则返回最后一个元素。`remove` 方法从列表中移除特定项。

lang = langs.pop(3)
print("{0} was removed".format(lang))

我们移除了索引为 3 的元素。`pop` 方法返回被移除元素的名称;它被打印到控制台。

lang = langs.pop()
print("{0} was removed".format(lang))

列表的最后一个元素,即 `"JavaScript"` 字符串,已从列表中移除。

langs.remove("Ruby")

此行从 `langs` 列表中删除 `"Ruby"` 字符串。

['Python', 'Ruby', 'Perl', 'Lua', 'JavaScript']
Lua was removed
JavaScript was removed
['Python', 'Ruby', 'Perl']
['Python', 'Perl']

从脚本的输出中,我们可以看到所描述方法的效果。

`del` 关键字也可以用来删除列表元素。

removing2.py
#!/usr/bin/python

# removing2.py

langs = ["Python", "Ruby", "Perl", "Lua", "JavaScript"]
print(langs)

del langs[1]
print(langs)

#del langs[15]

del langs[:]
print(langs)

我们有一个字符串列表。我们使用 `del` 关键字删除列表元素。

del langs[1]

我们删除了列表中的第二个字符串。它是 `"Ruby"` 字符串。

#del langs[15]

我们只能删除存在的元素。如果我们取消注释该代码行,我们会收到 `IndexError` 消息。

del langs[:]

在这里,我们删除了列表中的所有剩余元素。`[:]` 字符引用列表中的所有项。

$ ./removing2.py
['Python', 'Ruby', 'Perl', 'Lua', 'JavaScript']
['Python', 'Perl', 'Lua', 'JavaScript']
[]

Python 修改列表元素

在下一个示例中,我们将修改列表元素。

modifying.py
#!/usr/bin/python

# modifying.py

langs = ["Python", "Ruby", "Perl"]

langs.pop(2)
langs.insert(2, "PHP")
print(langs)

langs[2] = "Perl"
print(langs)

在示例中,我们两次修改了 `langs` 列表的第三个元素。

langs.pop(2)
langs.insert(2, "PHP")

修改元素的一种方法是删除它,然后在同一位置插入一个不同的元素。

langs[2] = "Perl"

另一种方法更直接。我们将一个新元素赋给一个给定的位置。现在第三个位置又有了 `"Perl"` 字符串。

$ ./modifying.py
['Python', 'Ruby', 'PHP']
['Python', 'Ruby', 'Perl']

Python 复制列表

在 Python 中有几种复制列表的方法。我们将提到其中一些。

copying.py
#!/usr/bin/python

# copying.py

import copy

w = ["Python", "Ruby", "Perl"]

c1 = w[:]
c2 = list(w)
c3 = copy.copy(w)
c4 = copy.deepcopy(w)
c5 = [e for e in w]

c6 = []

for e in w:
    c6.append(e)

c7 = []
c7.extend(w)

print(c1, c2, c3, c4, c5, c6, c7)

我们有一个包含三个字符串的列表。我们对列表进行了七次复制。

import copy

我们导入了 `copy` 模块,该模块有两种复制方法。

c1 = w[:]

使用切片语法复制列表。

c2 = list(w)

当 `list` 函数以列表作为参数时,它会创建列表的副本。

c3 = copy.copy(w)
c4 = copy.deepcopy(w)

`copy` 方法产生列表的浅拷贝。`deepcopy` 产生列表的深拷贝。

c5 = [e for e in w]

使用列表推导式创建字符串的副本。

c6 = []

for e in w:
    c6.append(e)

使用 `for` 循环创建的副本。

c7 = []
c7.extend(w)

还可以使用 `extend` 方法来创建副本。

$ ./copying.py
['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl']
['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl']
['Python', 'Ruby', 'Perl']

使用不同的技术创建了字符串列表的七个副本。

Python 索引列表元素

Python 列表中的元素可以通过其索引进行访问。索引号是整数;它们从零开始。索引可以是负数;负索引引用列表末尾的元素。列表中的第一个项索引为 0,最后一个项索引为 -1。

indexing.py
#!/usr/bin/python

# indexing.py

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

print(n[0])
print(n[-1])
print(n[-2])

print(n[3])
print(n[5])

我们可以通过索引访问列表的元素。索引放在列表名称后面的方括号 `[]` 内。

print(n[0])
print(n[-1])
print(n[-2])

这三行打印了列表的第一个、最后一个和倒数第二个项。

print(n[3])
print(n[5])

这两行打印了列表的第四个和第六个元素。

$ ./indexing.py
1
8
7
4
6

`index(e, start, end)` 方法查找特定元素并返回其最低索引。start 和 end 是可选参数,用于将搜索限制在给定边界内。

indexing2.py
#!/usr/bin/python

# indexing2.py

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

print(n.index(1))
print(n.index(2))

print(n.index(1, 1))
print(n.index(2, 2))

print(n.index(1, 2, 5))
print(n.index(3, 4, 8))

带有 `index` 方法的代码示例。

print(n.index(1))
print(n.index(2))

这两行打印了 n 列表中最左边的 1、2 值的索引。

print(n.index(1, 1))
print(n.index(2, 2))

在这里,我们在指定索引后搜索值 1 和 2。

print(n.index(1, 2, 5))

在这里,我们在索引为 2 和 5 的值之间搜索值 1。

$ ./indexing2.py
0
1
4
5
4
6

Python 切片列表

列表切片是一种操作,它从列表中提取某些元素并将它们组成另一个列表。可能具有不同的索引数量和不同的索引范围。

列表切片的语法如下:

[start:end:step]

语法中的 start、end、step 部分是整数。每个都是可选的。它们都可以是正数或负数。包含 end 索引的值不包含在切片中。

slice.py
#!/usr/bin/python

# slice.py

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

print(n[1:5])
print(n[:5])
print(n[1:])
print(n[:])

我们从八个整数的列表中创建了四个切片。

print(n[1:5])

第一个切片的值的索引为 1、2、3 和 4。新形成的列表是 [2, 3, 4, 5]。

print(n[:5])

如果省略 start 索引,则假定默认值为 0。切片是 [1, 2, 3, 4, 5]。

print(n[1:])

如果省略 end 索引,则取默认值 -1。在这种情况下,切片将取到列表末尾的所有值。

print(n[:])

甚至两个索引都可以省略。此语法创建列表的副本。

$ ./slice.py
[2, 3, 4, 5]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]

切片中的第三个索引是步长。它允许我们从列表中获取每 n 个值。

slice2.py
#!/usr/bin/python

# slice2.py

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

print(n[1:9:2])
print(n[::2])
print(n[::1])
print(n[1::3])

我们使用步长值形成了四个新列表。

print(n[1:9:2])

在这里,我们创建了一个切片,从第二个元素开始,到第八个元素结束,获取 n 列表中的每第二个元素。新列表包含以下元素:[2, 4, 6, 8]。

print(n[::2])

在这里,我们通过从列表的开头到结尾获取每第二个值来构建一个切片。

print(n[::1])

这创建了列表的副本。

print(n[1::3])

切片包含每第三个元素,从第二个元素开始到列表末尾。

$ ./slice2.py
[2, 4, 6, 8]
[1, 3, 5, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 5, 8]

索引可以是负数。负索引引用列表末尾的值。最后一个元素的索引是 -1,倒数第二个是 -2,依此类推。索引值较小的负数必须先出现在语法中。这意味着我们写成 [-6, -2] 而不是 [-2, -6]。后者会返回一个空列表。

slice3.py
#!/usr/bin/python

# slice3.py

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

print(n[-4:-1])
print(n[-1:-4])

print(n[-5:])
print(n[-6:-2:2])
print(n[::-1])

在此脚本中,我们形成了五个列表。我们还使用了负索引号。

print(n[-4:-1])
print(n[-1:-4])

第一行返回 [5, 6, 7],第二行返回一个空列表。较小的索引必须在较小的索引之前。

print(n[::-1])

这会创建一个反向列表。

$ ./slice3.py
[5, 6, 7]
[]
[4, 5, 6, 7, 8]
[3, 5]
[8, 7, 6, 5, 4, 3, 2, 1]

上述语法可用于赋值。赋值的右侧必须是一个可迭代对象。

slice4.py
#!/usr/bin/python

# slice4.py

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

n[0] = 10
n[1:3] = 20, 30
n[3::1] = 40, 50, 60, 70, 80

print(n)

我们有一个包含八个整数的列表。我们使用切片语法将元素替换为新值。

Python 遍历列表

本节将介绍在 Python 中遍历列表的三个基本方法。

traverse.py
#!/usr/bin/python

# traverse.py

n = [1, 2, 3, 4, 5]

for e in n:
    print(e, end=" ")

print()

第一种方法是最直接的遍历列表的方法。

n = [1, 2, 3, 4, 5]

我们有一个数字列表。列表中有五个整数。

for e in n:
    print(e, end=" ")

使用 `for` 循环,我们逐一遍历列表并将当前元素打印到控制台。

$ ./traverse.py
1 2 3 4 5

这是脚本的输出。整数被打印到终端。

第二个示例有点冗长。

traverse2.py
#!/usr/bin/python

# traverse2.py

n = [1, 2, 3, 4, 5]

i = 0
s = len(n)

while i < s:

    print(n[i], end=" ")
    i = i + 1

print()

我们正在使用 `while` 循环遍历列表。

i = 0
l = len(n)

首先,我们需要定义一个计数器并找出列表的大小。

while i < s:

    print(n[i], end=" ")
    i = i + 1

借助这两个数字,我们遍历列表并将每个元素打印到终端。

`enumerate` 内置函数在循环中为我们提供了列表的索引和值。

traverse3.py
#!/usr/bin/python

# traverse3.py

n = [1, 2, 3, 4, 5]

print(list(enumerate(n)))

for e, i in enumerate(n):
    print("n[{0}] = {1}".format(e, i))

在这个示例中,我们打印了值和值的索引。

$ ./traverse3.py
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
n[0] = 1
n[1] = 2
n[2] = 3
n[3] = 4
n[4] = 5

Python 计数列表元素

有时计数列表元素很重要。为此,Python 提供了 `count` 方法。

counting.py
#!/usr/bin/python

# counting.py

n = [1, 1, 2, 3, 4, 4, 4, 5]

print(n.count(4))
print(n.count(1))
print(n.count(2))
print(n.count(6))

在此示例中,我们计算了 `n` 列表中一些数字的出现次数。

n = [1, 1, 2, 3, 4, 4, 4, 5]

我们有一个整数列表。整数 1 和 4 出现了多次。

print(n.count(4))
print(n.count(1))
print(n.count(2))
print(n.count(6))

使用 `count` 方法,我们找出 4、1、2 和 6 的出现次数。

$ ./counting.py
3
2
1
0

数字 4 出现 3 次,1 出现 2 次,2 出现 1 次,6 不在列表中。

Python 嵌套列表

可以将列表嵌套到另一个列表中。使用嵌套列表会创建一个新的维度。要访问嵌套列表,需要额外的方括号 `[]`。

nested.py
#!/usr/bin/python

# nested.py

nums = [[1, 2], [3, 4], [5, 6]]

print(nums[0])
print(nums[1])
print(nums[2])

print(nums[0][0])
print(nums[0][1])

print(nums[1][0])
print(nums[2][1])

print(len(nums))

在此示例中,我们有三个嵌套列表,每个列表包含两个元素。

print(nums[0])
print(nums[1])
print(nums[2])

nums 列表中的三个嵌套列表被打印到控制台。

print(nums[0][0])
print(nums[0][1])

在这里,我们打印了第一个嵌套列表的两个元素。`nums[0]` 指的是第一个嵌套列表;`nums[0][0]` 指的是第一个嵌套列表的第一个元素,即 1。

print(len(nums))

该行打印 3。每个嵌套列表被算作一个元素。其内部元素不计入。

$ ./nested.py
[1, 2]
[3, 4]
[5, 6]
1
2
3
6
3

第二个示例具有其他维度。

nested2.py
#!/usr/bin/python

# nested2.py

nums = [[1, 2, [3, 4, [5, 6]]]]

print(nums[0])
print(nums[0][2])
print(nums[0][2][2])

print(nums[0][0])
print(nums[0][2][1])
print(nums[0][2][2][0])

在这个示例中,[5, 6] 列表嵌套到 [3, 4, ...] 列表中,[3, 4, [4, 6]] 嵌套到 [1, 2, ...] 列表中,而后者最终是 `nums` 列表的一个元素。

print(nums[0])
print(nums[0][2])
print(nums[0][2][2])

这三行将嵌套列表打印到控制台。

print(nums[0][0])
print(nums[0][2][1])
print(nums[0][2][2][0])

这里访问了三个元素。引用内部列表时需要额外的方括号 `[]`。

$ ./nested2.py
[1, 2, [3, 4, [5, 6]]]
[3, 4, [5, 6]]
[5, 6]
1
4
5

Python 排序列表

在本节中,我们将对列表元素进行排序。Python 有内置的列表方法 `sort` 和 `sorted` 函数用于排序。

sorting.py
#!/usr/bin/python

# sorting.py

n = [3, 4, 7, 1, 2, 8, 9, 5, 6]
print(n)

n.sort()
print(n)

n.sort(reverse=True)
print(n)

在代码示例中,我们有一个未排序的整数列表。我们使用 `sort` 方法对元素进行排序。该方法就地排序元素;原始列表会被修改。

n.sort()

`sort` 方法按升序对元素进行排序。

n.sort(reverse=True)

将 `reverse` 参数设置为 `True`,列表将按降序排序。

$ ./sorting.py
[3, 4, 7, 1, 2, 8, 9, 5, 6]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1]

在输出中,我们可以看到原始列表、按升序和降序排序的列表。

如果我们不想更改原始列表,可以使用 `sorted` 函数。此函数创建一个新的排序列表。

sorting2.py
#!/usr/bin/python

# sorting2.py

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

print(n)
print(sorted(n))
print(n)

在此示例中,我们使用 `sorted` 函数对列表的元素进行排序。

$ ./sorting2.py
[3, 4, 1, 7, 2, 5, 8, 6]
[1, 2, 3, 4, 5, 6, 7, 8]
[3, 4, 1, 7, 2, 5, 8, 6]

从脚本的输出中,我们可以看到原始列表没有被修改。

`sort` 方法有一个可选的 `key` 参数。该参数指定在进行比较之前要对每个列表元素调用的函数。

sorting3.py
#!/usr/bin/python

# sorting3.py

words = ["big", "Blue", "seven", "glass",
         "Green", "after", "Anctartica"]

words.sort()
print(words)

words.sort(key=str.lower)
print(words)

该示例生成区分大小写和不区分大小写的字符串比较。

words.sort(key=str.lower)

为了创建不区分大小写的比较,我们将 `str.lower` 函数添加到 `key` 参数。

$ ./sorting3.py
['Anctartica', 'Blue', 'Green', 'after', 'big', 'glass', 'seven']
['after', 'Anctartica', 'big', 'Blue', 'glass', 'Green', 'seven']

如果我们想对 Unicode 字符串进行排序,我们需要做额外的工作。

sorting_locale.py
#!/usr/bin/python

import locale
from functools import cmp_to_key

w = [u'zem', u'štebot', u'rum', u'železo', u'prameň', u"sob"]
locale.setlocale(locale.LC_COLLATE, ('sk_SK', 'UTF8'))

w.sort(key=cmp_to_key(locale.strcoll))

for e in w:
    print(e)

我们有一个包含六个 Unicode 字符串的列表。我们更改区域设置以根据当前语言选项对字符串进行排序。

import locale
from functools import cmp_to_key

我们导入了 `locale` 模块和 `cmp_to_key` 转换函数。

w = [u'zem', u'štebot', u'rum', u'železo', u'prameň', u"sob"]

这是一个包含六个字符串的列表。这些字符串是斯洛伐克语,并带有某些变音符号。它们在正确排序字符方面起着作用。

locale.setlocale(locale.LC_COLLATE, ('sk_SK', 'UTF8'))

我们设置了斯洛伐克语的区域设置。

w.sort(key=cmp_to_key(locale.strcoll))

我们对列表进行排序。`locale.strcoll` 根据当前的 `LC_COLLATE` 设置比较两个字符串。`cmp_to_key` 函数将一个 `旧式` 比较函数转换为一个键函数。

for e in w:
    print(e)

我们将排序后的单词打印到控制台。

$ ./sorting_locale.py
prameň
rum
sob
štebot
zem
železo

元素已正确排序。考虑了斯洛伐克字母的特性。

Python 反转列表元素

在 Python 中,我们可以通过几种方式反转列表中的元素。反转元素不应与反向排序混淆。

reversing.py
#!/usr/bin/python

# reversing.py

a1 = ["bear", "lion", "tiger", "eagle"]
a2 = ["bear", "lion", "tiger", "eagle"]
a3 = ["bear", "lion", "tiger", "eagle"]

a1.reverse()
print(a1)

it = reversed(a2)
r = list()

for e in it:
    r.append(e)

print(r)

print(a3[::-1])

在此示例中,我们有三个相同的字符串列表。我们以三种不同的方式反转元素。

a1.reverse()

第一种方法是使用 `reverse` 方法。

it = reversed(a2)
r = list()

for e in it:
    r.append(e)

`reversed` 函数返回一个反向迭代器。我们在 for 循环中使用迭代器并创建一个新的反向列表。

print(a3[::-1])

第三种方法是使用切片语法反转列表,其中步长参数设置为 -1。

$ ./reversing.py
['eagle', 'tiger', 'lion', 'bear']
['eagle', 'tiger', 'lion', 'bear']
['eagle', 'tiger', 'lion', 'bear']

这三个列表都已成功反转。

Python 列表推导式

列表推导式是一种创建列表的语法结构,该列表基于现有列表。其语法受到了集合的数学符号的影响。Python 语法受到 Haskell 编程语言的启发。

L = [expression for variable in sequence [if condition]]

上面的伪代码展示了列表推导式的语法。列表推导式创建一个新列表。它基于现有列表。for 循环遍历序列。对于每个循环,如果满足条件,则评估一个表达式。如果计算出值,则将其追加到新列表中。条件是可选的。

在可以使用 `map` 和 `filter` 以及/或嵌套循环的情况下,列表推导式提供了更简洁的创建列表的方法。

list_comprehension.py
#!/usr/bin/python

# list_comprehension.py

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

b = [e for e in a if e % 2]
print(b)

在此示例中,我们定义了一个数字列表。借助列表推导式,我们创建了一个不能被 2 整除(余数为零)的新数字列表。

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [e for e in a if e % 2]

这里是列表推导式。在 `for e in a` 循环中,取列表中的每个元素。然后测试 `if e % 2` 条件。如果满足条件,则评估一个表达式。在我们的例子中,表达式是纯粹的 `e`,它按原样获取元素。最后,将元素追加到列表中。

$ ./list_comprehension.py
[1, 3, 5, 7, 9]

列表中的数字不能被 2 整除(余数为零)。

在第二个示例中,我们将列表推导式与传统的 for 循环进行了比较。

list_comprehension2.py
#!/usr/bin/python

# list_comprehension2.py

lang = "Python"

a = []

for e in lang:
    a.append(ord(e))

b = [ord(e) for e in lang]

print(a)
print(b)

在此示例中,我们有一个字符串。我们想创建一个列表,其中包含字符串字母的 ASCII 整数代码。

a = []

for e in lang:
    a.append(ord(e))

我们使用 for 循环创建了这样一个列表。

b = [ord(e) for e in lang]

这里使用列表推导式生成了相同的内容。请注意,if 条件被省略了。它是可选的。

$ ./list_comprehension2.py
[80, 121, 116, 104, 111, 110]
[80, 121, 116, 104, 111, 110]

请查看 Python 列表推导式 以获取更多详细信息。

Python map 和 filter 函数

`map` 和 `filter` 函数是处理所有列表项的批量函数。它们是 Python 语言内置的函数式编程的一部分。

今天,建议在可能的情况下使用列表推导式代替这些函数。

map_fun.py
#!/usr/bin/python

# map_fun.py

def to_upper(s):

    return s.upper()

words = ["stone", "cloud", "dream", "sky"]

words2 = list(map(to_upper, words))
print(words2)

`map` 函数将特定函数应用于列表的每个元素。

def to_upper(s):

    return s.upper()

这是将应用于每个列表元素的函数的定义。它在给定的字符串上调用 `upper` 字符串方法。

words = ["stone", "cloud", "dream", "sky"]
words2 = map(to_upper, words)
print(words2)

`map` 函数将 `to_upper` 函数应用于 `words` 列表的每个字符串元素。然后返回一个新列表。我们将其打印到控制台。

$ ./map_fun.py
['STONE', 'CLOUD', 'DREAM', 'SKY']

列表的每个项都变成了大写字母。

`filter` 函数根据函数返回 true 的列表元素构建一个列表。

filter_fun.py
#!/usr/bin/python

# filter_fun.py

def positive(x):
    return x > 0

n = [-2, 0, 1, 2, -3, 4, 4, -1]

print(list(filter(positive, n)))

演示 `filter` 函数的示例。它将创建一个只包含正值的新列表。它将过滤掉所有负值和 0。

def positive(x):
    return x > 0

这是 `filter` 函数使用的函数的定义。它返回 `True` 或 `False`。返回布尔值的函数称为谓词。

$ ./filter_fun.py
[1, 2, 4, 4]

来源

Python 数据结构 - 语言参考

在本文中,我们描述了 Python 列表集合。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Python 教程