# Python 列表

> 原文： [http://zetcode.com/lang/python/lists/](http://zetcode.com/lang/python/lists/)

在 Python 编程教程的这一部分中，我们将更详细地介绍 Python 列表。

## Python 列表定义

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

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

## Python 列表索引

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

`simple.py`

```py
#!/usr/bin/env python

# simple.py

nums = [1, 2, 3, 4, 5]
print(nums)

```

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

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

```

这是示例的输出。

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

`various_types.py`

```py
#!/usr/bin/env python

# various_types.py

class Being:
    pass

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

```

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

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

```

这是输出。

## Python 列表初始化

有时我们需要预先初始化一个列表以具有特定数量的元素。

`initialization.py`

```py
#!/usr/bin/env python

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

print(n1)
print(n2)

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

print(n1)

```

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

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

```

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

```py
n1[0:11] = [10] * 10

```

前十个值将替换为 10s。

```py
$ ./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]

```

这是示例输出。

## Python 列表函数

`list()`函数从可迭代对象创建列表。 可迭代的对象可以是序列，支持迭代的容器或迭代器对象。 如果未指定任何参数，则创建一个新的空列表。

`list_fun.py`

```py
#!/usr/bin/env python

# list_fun.py

a = []
b = list()

print(a == b)

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

```

在示例中，我们创建一个空列表，一个元组列表，一个字符串和另一个列表。

```py
a = []
b = list()

```

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

```py
print(a == b)

```

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

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

```

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

```py
print(list("ZetCode"))

```

该行从字符串生成列表。

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

```

最后，我们创建一个字符串列表的副本。

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

```

这是示例输出。

## Python 列表操作

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

`list_oper.py`

```py
#!/usr/bin/env 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)

```

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

```py
print(n1 == n2)

```

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

```py
print(n1 + n2)

```

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

```py
print(n1 * 3)

```

我们在列表上使用乘法运算符。 它重复元素 n 次； 在我们的情况下是三遍。

```py
print(2 in n1)

```

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

```py
$ ./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`

```py
#!/usr/bin/env 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()`。

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

```

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

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

```

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

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

```

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

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

```

这是输出。

## Python 添加列表元素

本节将显示如何将元素添加到 Python 列表中。

`adding.py`

```py
#!/usr/bin/env 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()`。

```py
langs = []

```

创建一个空列表。

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

```

`append()`方法将一个项目添加到列表的末尾； 我们附加两个字符串。

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

```

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

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

```

`extend()`方法将值的序列添加到列表的末尾。 在我们的例子中，两个 Python 元组字符串附加在列表的末尾。

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

```

这是示例输出。

## IndexError

列表下标超出范围时，将引发`IndexError`。

`index_error.py`

```py
#!/usr/bin/env 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。使用较大的索引会导致错误。

```py
n[6] = 60

```

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

```py
except IndexError as e:

    print(e)

```

我们使用`except`子句捕获错误。 在子句的正文中，我们显示错误消息。

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

```

这是示例输出。

## TypeError

如果元组的索引不是纯整数，则会抛出`TypeError`。

`type_error.py`

```py
#!/usr/bin/env 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`。

```py
print(n['2'])

```

列表索引必须是整数。 其他类型以错误结尾。

```py
except TypeError as e:

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

```

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

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

```

这是示例输出。

## 从 Python 列表中删除元素

以前，我们已将项目添加到列表中。 现在，我们将从列表中删除它们。

`removing.py`

```py
#!/usr/bin/env 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()`方法从列表中删除特定项目。

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

```

我们删除具有索引 3 的元素。`pop()`方法返回已删除元素的名称； 它被打印到控制台。

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

```

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

```py
langs.remove("Ruby")

```

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

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

```

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

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

`removing2.py`

```py
#!/usr/bin/env python

# removing2.py

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

del langs[1]
print(langs)

#del langs[15]

del langs[:]
print(langs)

```

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

```py
del langs[1]

```

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

```py
#del langs[15]

```

我们只能删除现有元素。 如果取消注释代码行，我们将收到`IndexError`消息。

```py
del langs[:]

```

在这里，我们从列表中删除所有剩余的元素。 `[:]`字符表示列表的所有项目。

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

```

这是示例输出。

## Python 修改列表元素

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

`modifying.py`

```py
#!/usr/bin/env python

# modifying.py

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

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

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

```

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

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

```

修改元素的一种方法是将其删除，然后将另一个元素放置在同一位置。

```py
langs[2] = "Perl"

```

另一种方法更简单。 我们在给定位置分配一个新元素。 现在，在第三个位置再次有`"Perl"`字符串。

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

```

这是示例输出。

## Python 复制列表

我们可以通过多种方式在 Python 中复制列表。 我们将提及其中的一些。

`copying.py`

```py
#!/usr/bin/env 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)

```

我们列出了三个字符串。 我们将列表复制了七次。

```py
import copy

```

我们导入`copy`模块，其中有两种复制方法。

```py
c1 = w[:]

```

使用切片语法复制列表。

```py
c2 = list(w)

```

当`list()`函数将列表作为参数时，它会创建一个列表副本。

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

```

`copy()`方法产生列表的浅表副本。 `deepcopy()`产生列表的深层副本。

```py
c5 = [e for e in w]

```

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

```py
c6 = []

for e in w:
    c6.append(e)

```

由`for`循环创建的副本。

```py
c7 = []
c7.extend(w)

```

`extend()`方法也可用于创建副本。

```py
$ ./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`

```py
#!/usr/bin/env 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])

```

我们可以通过其索引访问列表的元素。 索引位于列表名称后方括号`[]`之间。

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

```

这三行将打印列表的第一，最后和最后一个项目。

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

```

两行显示列表的第四和第六个元素。

```py
$ ./indexing.py
1
8
7
4
6

```

这是示例输出。

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

`indexing2.py`

```py
#!/usr/bin/env 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()`方法的代码示例。

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

```

这两行显示 n 列表中最左边的 1、2 值的索引。

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

```

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

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

```

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

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

```

这是示例输出。

## Python 切片列表

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

列表切片的语法如下：

```py
[start:end:step]

```

语法的开始，结束，步骤部分是整数。 它们每个都是可选的。 它们可以是正面的也可以是负面的。 具有结束索引的值不包括在切片中。

`slice.py`

```py
#!/usr/bin/env python

# slice.py

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

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

```

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

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

```

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

```py
print(n[:5])

```

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

```py
print(n[1:])

```

如果省略了结束索引，则采用-1 默认值。 在这种情况下，切片将所有值带到列表的末尾。

```py
print(n[:])

```

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

```py
$ ./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`

```py
#!/usr/bin/env 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])

```

我们使用`step`值形成四个新列表。

```py
print(n[1:9:2])

```

在这里，我们创建一个切片，该切片具有从 n 列表开始的每个第二元素，从第二个元素开始，以第八个元素结束。 新列表具有以下元素：`[2, 4, 6, 8]`。

```py
print(n[::2])

```

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

```py
print(n[::1])

```

这将创建一个列表的副本。

```py
print(n[1::3])

```

切片具有第二个元素，从第二个元素到列表的末尾。

```py
$ ./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`

```py
#!/usr/bin/env 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])

```

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

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

```

第一行返回`[5, 6, 7]`，第二行返回一个空列表。 较低的索引必须先于较高的索引。

```py
print(n[::-1])

```

这将创建一个反向列表。

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

```

示例的输出。

上面提到的语法可以在分配中使用。 赋值的右侧必须有一个可迭代的对象。

`slice4.py`

```py
#!/usr/bin/env 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`

```py
#!/usr/bin/env python

# traverse.py

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

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

print() 

```

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

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

```

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

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

```

使用`for`循环，我们一张一张地浏览列表，然后将当前元素打印到控制台。

```py
$ ./traverse.py
1 2 3 4 5

```

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

第二个示例更为详细。

`traverse2.py`

```py
#!/usr/bin/env 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`循环遍历列表。

```py
i = 0
l = len(n)

```

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

```py
while i < s:

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

```

在这两个数字的帮助下，我们遍历列表并将每个元素打印到终端。

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

`traverse3.py`

```py
#!/usr/bin/env 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))

```

在示例中，我们打印值和值的索引。

```py
$ ./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`

```py
#!/usr/bin/env 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`列表中几个数字的出现次数。

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

```

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

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

```

使用`count()`方法，我们发现 4、1、2 和 6 个数字的出现。

```py
$ ./counting.py
3
2
1
0

```

数字 4 出现 3 次，1 次两次，2 次一次以及 6 在列表中不存在。

## Python 嵌套列表

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

`nested.py`

```py
#!/usr/bin/env 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))

```

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

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

```

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

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

```

在这里，我们打印第一个嵌套列表的两个元素。 `nums[0]`引用第一个嵌套列表； `nums[0][0]`引用第一个嵌套列表的第一个元素，即 1。

```py
print(len(nums))

```

该行显示 3。每个嵌套列表都计为一个元素。 不考虑其内部元素。

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

```

这是示例输出。

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

`nested2.py`

```py
#!/usr/bin/env 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`列表的元素。

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

```

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

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

```

在此访问三个元素。 引用内部列表时，需要其他方括号`[]`。

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

```

这是示例输出。

## Python 排序列表

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

`sorting.py`

```py
#!/usr/bin/env 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()`方法对元素进行排序。 该方法对元素进行原位排序； 原始列表已修改。

```py
n.sort()

```

`sort()`方法以升序对元素进行排序。

```py
n.sort(reverse=True)

```

将反向参数设置为`True`时，列表以降序排序。

```py
$ ./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`

```py
#!/usr/bin/env python

# sorting2.py

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

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

```

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

```py
$ ./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`

```py
#!/usr/bin/env python

# sorting3.py

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

words.sort()
print(words)

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

```

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

```py
words.sort(key=str.lower)

```

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

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

```

这是示例输出。

如果要对 Unicode 字符串进行排序，我们需要做其他工作。

`sorting_locale.py`

```py
#!/usr/bin/env 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 字符串的列表。 我们更改语言环境设置，以根据当前语言选项对字符串进行排序。

```py
import locale
from functools import cmp_to_key

```

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

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

```

这是六个字符串的列表。 字符串使用斯洛伐克语，并带有一些变音标记。 它们在正确排序字符方面发挥作用。

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

```

我们为斯洛伐克语设置了语言环境。

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

```

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

```py
for e in w:
    print(e)

```

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

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

```

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

## Python 反转列表元素

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

`reversing.py`

```py
#!/usr/bin/env 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])

```

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

```py
a1.reverse()

```

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

```py
it = reversed(a2)
r = list()

for e in it:
    r.append(e)

```

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

```py
print(a3[::-1])

```

第三种方法是使用`slice`语法反转列表，其中`step`参数设置为-1。

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

```

三个列表全部颠倒了。

## Python 列表推导式

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

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

```

上面的伪代码显示了列表推导式的语法。 列表推导式会创建一个新列表。 它基于现有列表。 `for`循环遍历整个序列。 对于每个循环，如果满足条件，则对表达式进行求值。 如果计算出该值，它将被添加到新列表中。 条件是可选的。

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

`list_comprehension.py`

```py
#!/usr/bin/env 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 而没有余数。

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

```

这是九个整数的列表。

```py
b = [e for e in a if e % 2]

```

这里我们有列表推导式。 在`for e in a`循环中，获取列表的每个元素。 然后测试`if e % 2`条件。 如果满足条件，则对表达式求值。 在我们的例子中，表达式是一个纯`e`，它直接使用元素。 最后，元素被添加到列表中。

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

```

示例输出。 列表中的数字不能除以 2，不能有余数。

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

`list_comprehension2.py`

```py
#!/usr/bin/env 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 整数代码的列表。

```py
a = []

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

```

我们使用`for`循环创建这样的列表。

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

```

这里使用列表推导产生相同的结果。 注意，省略了`if`条件。 它是可选的。

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

```

这是示例输出。 您可以在 [Python 列表推导](/articles/pythonlistcomprehensions/)教程中找到有关列表推导的更多信息。

## Python 映射和过滤器函数

`map()`和`filter()`函数是可在所有列表项上使用的质量函数。 它们是 Python 语言内置的函数编程的一部分。

今天，建议尽可能使用列表推导代替这些函数。

`map_fun.py`

```py
#!/usr/bin/env 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()`函数将特定函数应用于列表的每个元素。

```py
def to_upper(s):

    return s.upper()

```

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

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

```

这是字符串列表。

```py
words2 = map(to_upper, words)
print(words2)

```

`map()`函数将`to_upper()`函数应用于单词列表的每个字符串元素。 形成一个新列表并返回。 我们将其打印到控制台。

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

```

列表中的每一项均以大写字母表示。

`filter()`函数从列表的那些元素中为函数返回`true`的列表构造一个列表。

`filter_fun.py`

```py
#!/usr/bin/env 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。

```py
def positive(x):
    return x > 0

```

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

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

```

`filter_fun.py`脚本的输出。

在 Python 教程的这一部分中，我们描述了 Python 列表。