Python 包含丰富的内置集合类型选择,这些集合类型通常完全足以支持即使是非常复杂的程序,而无需定义我们自己的数据结构。现在,我们将对这些基本集合类型中的一些进行概述—足以让我们编写一些有趣的代码—尽管我们将在后面的章节中重新讨论这些集合类型中的每一种,以及其他一些集合类型。
让我们从以下类型开始:
str
–Unicode 代码点的不可变字符串bytes
-不可变的字节字符串list
-对象的可变序列dict
-从键到值的可变映射
在此过程中,我们还将介绍 Python 的for
循环。
Python 中的字符串具有数据类型str
,我们已经广泛使用了它们。字符串是一个 Unicode 代码点序列,在大多数情况下,您可以将代码点视为类似于字符,尽管它们不是严格等价的。Python 字符串中的代码点序列是不可变的,因此一旦构建了字符串,就不能修改其内容。
代码点、字母、字符和标志符号之间的差异可能会令人困惑。让我们试着用一个例子来说明:希腊大写字母∑(sigma),当然在希腊文本的写作中被广泛使用,数学家也用它来表示一系列的总和。字母 sigma 的这两种用法分别由称为希腊大写字母 sigma 和 N 元求和的不同 Unicode 字符表示。通常,如果使用同一个字母来传达不同的
信息,则使用不同的 Unicode 字符。另一个例子是希腊大写字母 OMEGA 和欧姆符号,电阻单位的符号。代码点是组成代码空间的数值集合的任何一个成员。每个字符都与一个代码点相关联,因此希腊文大写字母 SIGMA 被分配给U+03A3
,N 元求和被分配给U+2211
。正如我们在这里所做的那样,代码点通常以 U+nnnn 形式编写,其中 nnnn 是一个四位、五位或六位的十六进制数。并非所有代码点都已分配给字符。例如,U+0378
是一个未分配的代码点,没有什么可以阻止您在 Pythonstr
中使用\u0378
转义序列包含此代码点;因此,str
实际上是一个代码点序列,而不是一个字符序列。虽然在 Python 的上下文中没有使用术语 in,但为了完整性,我们认为应该指出 glyph 是字符的视觉表示。不同的字符,例如希腊大写字母 SIGMA 和 N 元求和,可以使用相同的标志符号,也可以使用不同的标志符号,具体取决于使用的字体。
Python 中的文字字符串由引号分隔:
>>> 'This is a string'
您可以使用单引号,正如我们上面提到的那样。也可以使用双引号,如下所示:
>>> "This is also a string"
然而,你必须始终如一。例如,不能将双引号与单引号配对使用:
>>> "inconsistent'
File "<stdin>", line 1
"inconsistent'
^
SyntaxError: EOL while scanning string literal
支持这两种引用样式,可以轻松地将另一个引用字符合并到文字字符串中,而无需使用难看的转义字符:
>>> "It's a good thing."
"It's a good thing."
>>> '"Yes!", he said, "I agree!"'
'"Yes!", he said, "I agree!"'
请注意,REPL 在将字符串回显给我们时利用了相同的引用灵活性。
以下图像中的文字“禅宗时刻:实用性胜过纯洁性”——漂亮的文本字符串,以文字形式呈现。简单优雅:
Figure 2.1: Moment of zen: Practicality beats purity Moment of zen
乍一看,对这两种引用风格的支持似乎违反了 Pythonic 风格的一个重要原则。来自 Python 的禅宗:
应该有一个——最好只有一个——显而易见的方法来做到这一点。
然而,在这种情况下,来自同一来源的另一句格言优先:
实用胜过纯洁
支持两种引用样式的实用性比另一种更受重视:一种引用样式与更频繁地使用丑陋的转义序列相结合,我们将很快遇到这种情况。
Python 编译器将相邻的文字字符串连接成单个字符串:
>>> "first" "second"
'firstsecond'
虽然一开始这似乎毫无意义,但它对于很好地格式化代码非常有用,我们将在后面看到。
如果需要包含换行符的文字字符串,有两个选项:
- 使用多行字符串,
- 使用转义序列。
首先,让我们看看多行字符串。多行字符串由三个引号字符而不是一个引号字符分隔。下面是一个使用三个双引号的示例:
>>> """This is
... a multiline
... string"""
'This is\na multiline\nstring'
注意,当字符串回显给我们时,换行符是如何由\n
转义序列表示的。
我们还可以使用三个单引号:
>>> '''So
... is
... this.'''
'So\nis\nthis.'
作为使用多行引用的替代方法,我们可以自己嵌入控制字符:
>>> m = 'This string\nspans mutiple\nlines'
>>> m
'This string\nspans mutiple\nlines'
为了更好地理解我们在本例中所表示的内容,我们可以使用内置的print()
函数查看字符串:
>>> print(m)
This string
spans mutiple
lines
如果您在 Windows 上工作,您可能会认为换行符应该由回车符、换行符对联\r\n
表示,而不仅仅是换行符\n
。Python 不需要这样做,因为 Python3 有一个名为通用换行符支持的功能,它可以从简单的\n
转换为平台在输入和输出方面的本机换行符序列。您可以在PEP 278中阅读更多有关通用新线支持的信息。
我们也可以将转义序列用于其他目的,例如将制表符与\t
合并,或在字符串中使用引号字符与\
:
>>> "This is a \" in a string"
'This is a " in a string'
反过来说:
>>> 'This is a \' in a string'
"This is a ' in a string"
如您所见,Python 在使用最方便的引号分隔符方面比我们更聪明,尽管当我们在字符串中使用两种类型的引号时,Python 也会求助于转义序列:
>>> 'This is a \" and a \' in a string'
'This is a " and a \' in a string'
因为反斜杠有特殊的含义,所以要在字符串中放置反斜杠,我们必须将反斜杠本身转义:
>>> k = 'A \\ in a string'
'A \\ in a string'
为了让我们自己确信,这个字符串中实际上只有一个反斜杠,我们可以print()
它:
>>> print(k)
A \ in a string
您可以在 Python 文档中阅读更多关于转义序列的信息。
有时,特别是在处理大量使用反斜杠的字符串(如 Windows 文件系统路径或正则表达式模式)时,对反斜杠进行加倍的要求可能很难看,而且容易出错。Python 用它的原始字符串来拯救它。原始字符串不支持任何转义序列,并且在很大程度上是您看到的就是您得到的。要创建原始字符串,请在开头引号前面加上小写字母r
:
>>> path = r'C:\Users\Merlin\Documents\Spells'
>>>
>>> path
'C:\\Users\\Merlin\\Documents\\Spells'
>>> print(path)
C:\Users\Merlin\Documents\Spells
Although it's common to store and manipulate filesystem paths as strings, for anything but the most straightforward path handling, you should investigate the Python Standard Library pathlib
module.
我们可以使用str
构造函数创建其他类型的字符串表示,例如整数:
>>> str(496)
>>> '496'
或floats
:
>>> str(6.02e23)
'6.02e+23'
Python 中的字符串是所谓的序列类型,这意味着它们支持查询有序元素序列的某些常见操作。例如,我们可以使用方括号和基于零的整数索引访问单个字符:
>>> s = 'parrot'
>>> s[4]
'o'
与许多其他编程语言相比,没有与字符串类型不同的单独字符类型。索引操作返回一个完整的字符串,该字符串只包含一个代码点元素,我们可以使用 Python 的内置type()
函数演示这一事实:
>>> type(s[4])
<class 'str'>
我们将在本书后面更多地介绍类型和类。
String
对象还支持作为方法实现的各种操作。我们可以在字符串类型上使用help()
列出这些方法:
>>> help(str)
当您按回车时,您会看到如下显示:
Help on class str in module builtins:
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object. If encoding or
| errors is specified, then the object must expose a data buffer
| that will be decoded using the given encoding and error handler.
| Otherwise, returns the result of object.__str__() (if defined)
| or repr(object).
| encoding defaults to sys.getdefaultencoding().
| errors defaults to 'strict'.
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
| __eq__(self, value, /)
:
在任何平台上,您都可以通过按空格键浏览帮助页面,一次前进一页,直到看到capitalize()
方法的文档,跳过以双下划线开头和结尾的所有方法:
| Create and return a new object. See help(type) for accurate
| signature.
|
| __repr__(self, /)
| Return repr(self).
|
| __rmod__(self, value, /)
| Return value%self.
|
| __rmul__(self, value, /)
| Return self*value.
|
| __sizeof__(...)
| S.__sizeof__() -> size of S in memory, in bytes
|
| __str__(self, /)
| Return str(self).
|
| capitalize(...)
| S.capitalize() -> str
|
| Return a capitalized version of S, i.e. make the first
| character have upper case and the rest lower case.
|
:
按Q退出帮助浏览器,我们将尝试使用captialize()
。让我们制作一个值得资本化的字符串——一个首都的名称!
>>> c = "oslo"
为了在 Python 中调用对象上的方法,我们在对象名之后和方法名之前使用点。方法是函数,因此我们必须使用括号来指示应该调用该方法。
>>> c.capitalize()
'Oslo'
请记住,字符串是不可变的,因此capitalize()
方法没有适当地修改c
。相反,它返回了一个新字符串。我们可以通过显示保持不变的c
来验证这一点:
>>> c
'oslo'
通过浏览帮助,您可能想花一点时间熟悉字符串类型提供的各种有用方法。
字符串完全支持 Unicode,因此您可以轻松地将其用于国际字符,甚至是文字,因为 Python 3 的默认源代码编码是 UTF-8。例如,如果您可以访问挪威字符,则只需输入以下内容:
>>> "Vi er så glad for å høre og lære om Python!"
'Vi er så glad for å høre og lære om Python!'
或者,您可以使用 Unicode 代码点的十六进制表示形式作为前缀为\u
的转义序列:
>>> "Vi er s\u00e5 glad for \u00e5 h\xf8re og l\u00e6re om Python!"
'Vi er så glad for å høre og lære om Python!'
不过,我们相信你会同意,这有点不方便。
类似地,您可以使用后跟 2 个字符的十六进制字符串的\x
转义序列在string
文本中包含一个字节的 Unicode 代码点:
>>> '\xe5'
'å'
您甚至可以使用转义的八进制字符串,使用单个齿隙后跟 0 到 7 范围内的三位数字,尽管我们承认,我们从未在实践中见过这种用法,只是无意中被用作 bug:
>>> '\345'
'å'
在其他类似的字节类型中没有这样的 Unicode 功能,我们将在下一步介绍。
字节类型类似于str
类型,除了每个实例不是一个 Unicode 代码点序列,而是一个bytes
序列。因此,bytes
对象用于原始二进制数据和固定宽度的单字节字符编码,如 ASCII。
与字符串一样,它们有一个简单的文本形式,由单引号或双引号分隔,尽管对于文本字节,开头引号必须以小写字母b
开头:
>>> b'data'
b'data'
>>> b"data"
b'data'
还有一个bytes
构造函数,但它的行为相当复杂,我们将其介绍推迟到本系列的第二本书Python 熟练工中。在我们的旅程中的这一点上,我们可以识别bytes
文本,并了解它们支持许多与str
相同的操作,例如索引和拆分:
>>> d = b'some bytes'
>>> d.split()
[b'some', b'bytes']
您将看到,split()
方法返回字节对象列表。
要在字节和str
之间转换,我们必须知道用于将字符串的 Unicode 代码点表示为字节的字节序列的编码。Python 支持多种所谓的编解码器,如 UTF-8、UTF-16、ASCII、拉丁语-1、Windows-1251 等–有关当前编解码器列表,请参阅 Python 文档
在 Python 中,我们可以将一个 Unicodestr
编码为bytes
对象,反过来我们可以将一个bytes
对象解码为 Unicodestr
。在任何一个方向上,都由我们来指定编码。Python 不会——一般来说也无法阻止您使用CP037
编解码器(用于处理遗留 IBM 大型机上的字符串)错误地解码存储在 bytes 对象中的 UTF-16 数据。
如果幸运的话,解码会在运行时失败,出现一个UnicodeError
;如果你运气不好,你会得到一堆垃圾,而这些垃圾不会被你的程序发现。
Figure 2.2: Encoding and Decoding.
让我们以一个有趣的 Unicode 字符串开始一个关于字符串的交互式会话,该字符串包含 29 个字母的挪威字母表的所有字符–pangram:
>>> norsk = "Jeg begynte å fortære en sandwich mens jeg kjørte taxi på vei til quiz"
现在,我们将使用 UTF-8 编解码器,使用str
对象的encode()
方法将其编码为bytes
对象:
>>> data = norsk.encode('utf-8')
>>> data
b'Jeg begynte \xc3\xa5 fort\xc3\xa6re en sandwich mens jeg kj\xc3\xb8rte taxi p\xc3\xa5 vei til quiz'
查看如何将每个挪威字母呈现为一对字节。
我们可以使用 bytes 对象的decode()
方法反转该过程。同样,由我们提供正确的编码:
>>> norwegian = data.decode('utf-8')
我们可以检查编码/解码往返给我们的结果是否与我们开始时相同:
>>> norwegian == norsk
True
让我们试着把它显示出来:
>>> norwegian
'Jeg begynte å fortære en sandwich mens jeg kjørte taxi på vei til quiz'
在这个关头,所有这些乱七八糟的编码似乎都是不必要的细节——特别是在英语环境中操作时——但理解这一点至关重要,因为文件和网络资源(如 HTTP 响应)都是以字节流的形式传输的,而我们更喜欢使用 Unicode 字符串。
String differences between Python 3 and Python 2
The biggest difference between contemporary Python 3 and legacy Python 2 is the handling of strings. In versions of Python up to and including Python 2 the str
type was a so-called byte string, where each character was encoded as a single byte
. In this sense, Python 2 str
was similar to the Python 3 bytes
, however, the interface presented by str
and bytes
is in fact different in significant ways. In particular their constructors are completely different and indexing into a bytes
object returns an integer rather than a single code point string. To confuse matters further, there is also a bytes
type in Python 2.6 and Python 2.7, but this is just a synonym for str
and as such has an identical interface. If you're writing text handling code intended to be portable across Python 2 and Python 3 – which is perfectly possible – tread carefully!
Python 列表,比如 stringsplit()
方法返回的列表,是对象序列。与字符串不同,列表是可变的,只要其中的元素可以替换或删除,并且可以插入或追加新元素。列表是 Python 数据结构的主力。
文字列表用方括号分隔,列表中的项目用逗号分隔。以下是三个数字的列表:
>>> [1, 9, 8]
[1, 9, 8]
下面是三个字符串的列表:
>>> a = ["apple", "orange", "pear"]
我们可以使用带零基索引的方括号检索元素:
>>> a[1]
"orange"
我们可以通过指定给特定元素来替换元素:
>>> a[1] = 7
>>> a
['apple', 7, 'pear']
查看列表如何在所包含对象的类型方面具有异构性。我们现在有一个包含一个str
、一个int
和另一个str
的列表。
创建空列表通常很有用,我们可以使用空方括号:
>>> b = []
我们可以用其他方式修改列表。让我们使用append()
方法在列表末尾添加一些浮动:
>>> b.append(1.618)
>>> b
[1.618]
>>> b.append(1.414)
[1.618, 1.414]
还有许多其他有用的方法用于处理列表,我们将在后面的章节中介绍。现在,我们只需要能够执行基本的列表操作。
还有一个list
构造函数,可用于从其他集合创建列表,例如字符串:
>>> list("characters")
['c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', 's']
虽然 Python 中重要的空格规则一开始看起来非常僵硬,但是有很多灵活性。例如,如果一行末尾有未闭合的括号、大括号或圆括号,则可以继续下一行。这对于表示长文字集合或提高短集合的可读性非常有用:
>>> c = ['bear',
... 'giraffe',
... 'elephant',
... 'caterpillar',]
>>> c
['bear', 'giraffe', 'elephant', 'caterpillar']
另请参见如何允许在最后一个元素后使用额外的逗号,这是一个提高代码可维护性的方便特性。
字典——具体体现在dict
类型中——是 Python 语言
工作方式的基础,并且被广泛使用。字典将键
映射到值,在某些语言中称为映射或关联数组。让我们看看如何在 Python 中创建和使用字典。
文字字典是使用包含键值对的大括号创建的。每一对用逗号分隔,每一个键用冒号与其对应的值分隔。在这里,我们使用字典创建一个简单的电话目录:
>>> d = {'alice': '878-8728-922', 'bob': '256-5262-124',
'eve': '198-2321-787'}
我们可以使用方括号运算符按键检索项目:
>>> d['alice']
'878-8728-922'
我们可以通过方括号赋值来更新与特定键相关的值:
>>> d['alice'] = '966-4532-6272'
>>> d
{'bob': '256-5262-124', 'eve': '198-2321-787',
'alice': '966-4532-6272'}
如果我们分配给尚未添加的密钥,将创建一个新条目:
>>> d['charles'] = '334-5551-913'
>>> d
{'bob': '256-5262-124', 'eve': '198-2321-787',
'charles': '334-5551-913', 'alice': '966-4532-6272'}
请注意,不能依赖字典中的条目以任何特定顺序存储,事实上,Python 选择的顺序甚至可能在同一程序的运行之间发生变化。与列表类似,可以使用空大括号创建空词典:
>>> e = {}
这是一本非常粗略的词典,但我们将在第 5 章探索内置集合类型中更详细地回顾它们。
现在我们已经有了制作一些有趣的数据结构的工具,我们将看一下 Python 的另一种循环构造,for
-loop。Python 中的for
循环对应于许多其他编程语言中的for-each
循环。他们从集合中一个接一个地请求项——或者更严格地说,从一个 iterable 系列中请求项(但以后会更多)——然后依次将它们分配给我们指定的 a 变量。让我们创建一个列表集合,并使用for
-循环对其进行迭代,记住将for
-循环中的代码缩进四个空格:
>>> cities = ["London", "New York", "Paris", "Oslo", "Helsinki"]
>>> for city in cities:
... print(city)
...
London
New York
Paris
Oslo
Helsinki
因此,在列表上迭代会逐个生成项目。如果您在字典上迭代,您只会得到看似随机的键,然后可以在for
-循环体中使用这些键来检索相应的值。让我们定义一个字典,将颜色名称字符串映射到存储为整数的十六进制整数颜色代码:
>>> colors = {'crimson': 0xdc143c, 'coral': 0xff7f50,
'teal': 0x008080}
>>> for color in colors:
... print(color, colors[color])
...
coral 16744272
crimson 14423100
teal 32896
在这里,我们使用内置的print()
函数的功能来接受多个参数,分别传递每种颜色的键和值。另请参见返回给我们的颜色代码是如何以十进制表示的。
现在,在我们将所学的部分内容整合到一个有用的程序中之前,请练习在 Windows 上使用Ctrl+Z或在 Mac 或 Linux 上使用Ctrl+D退出 Python REPL。
让我们绕过一小段时间,尝试一下我们在一个更大的例子中介绍的一些工具。教科书通常避免这种实用主义,特别是在早期章节,但我们认为将新思想应用到实际情况中是很有趣的。为了避免在风格上出错,我们需要引入一些“黑盒”组件来完成这项工作,但稍后您将详细了解它们,所以不要担心。
我们将在 REPL 处编写一个较长的代码段,并简要介绍 with 语句。我们的代码将使用一个名为urlopen()
的 Python 标准库函数从 web 上获取一些经典文献的文本数据。这是在 REPL 输入的完整代码。我们用行号注释了此代码段,以便于引用解释中的行:
>>> from urllib.request import urlopen
>>> with urlopen('http://sixty-north.com/c/t.txt') as story:
... story_words = []
... for line in story:
... line_words = line.split()
... for word in line_words:
... story_words.append(word)
...
我们将处理这段代码,依次解释每一行。
-
要访问
urlopen()
我们需要从request
模块导入函数,该模块本身位于标准库urllib
包中。 -
我们将使用故事文本的 URL 调用
urlopen()
。我们使用一个名为with
-block 的 Python 构造来管理从 URL 获取的资源,因为从 web 获取资源需要操作系统套接字等。我们将在后面的一章中更多地讨论 with 语句,但现在我们只需要知道,对使用外部资源的对象使用 with 语句是避免所谓的资源泄漏的良好实践。with 语句调用urlopen()
函数并将响应对象绑定到名为 story 的变量。 -
请注意,with 语句以冒号结尾,冒号引入了一个新块,因此在该块中我们必须缩进四个空格。我们创建一个空列表,它最终将保存检索到的文本中的所有单词。
-
我们打开一个
for
循环,它将在故事中循环。回想一下,for
-循环从 in 关键字右侧的表达式中逐个请求项目-在本例中为故事-并将它们依次分配给左侧的名称-在本例中为行。这样,当以这种方式迭代时,故事引用的那种类型的HTTP
响应对象会从响应体中产生连续的文本行,因此for
-循环一次从故事中检索一行文本。for 语句也以冒号结尾,因为它引入了for
-循环的主体,这是一个新的块,因此是一个更高级别的缩进。 -
在文本的
for each
行中,我们使用split()
方法将其划分为空白边界上的单词,从而生成一个我们称为line_words
的单词列表。 -
现在我们使用嵌套在第一个循环中的第二个
for
-循环来迭代这个单词列表。 -
我们
append()
将每个单词依次添加到story_words
列表中。 -
最后,我们在三点提示下输入一个空行,以关闭所有打开的块-在本例中,内部
for
-循环、外部for
-循环和 with 块都将终止。该块将被执行,在短暂的延迟之后,Python 现在返回到常规的三箭头提示符。此时,如果 Python 给您一个错误,例如SyntaxError
或IndentationError
,您应该返回,检查您输入的内容,并小心地重新输入代码,直到 Python 毫无怨言地接受整个代码块。如果您得到一个HTTPError
,那么您无法通过 Internet 获取资源,您应该检查您的网络连接或稍后重试,尽管值得检查您键入的 URL 是否正确。
我们可以通过让 Python 评估story_words
的值来查看我们收集的单词:
>>> story_words
[b'It', b'was', b'the', b'best', b'of', b'times', b'it', b'was', b'the', b'worst', b'of', b'times',b'it', b'was', b'the', b'age', b'of', b'wisdom', b'it', b'was', b'the', b'age', b'of', b'foolishness', b'it', b'was', b'the', b'epoch', b'of', b'belief', b'it', b'was', b'the', b'epoch', b'of', b'incredulity', b'it', b'was', b'the', b'season', b'of', b'Light', b'it', b'was', b'the', b'season', b'of', b'Darkness', b'it', b'was', b'the', b'spring', b'of', b'hope', b'it', b'was', b'the', b'winter', b'of', b'despair', b'we', b'had', b'everything', b'before', b'us', b'we', b'had', b'nothing', b'before', b'us', b'we', b'were', b'all', b'going', b'direct', b'to', b'Heaven', b'we', b'were', b'all', b'going', b'direct', b'the', b'other', b'way', b'in', b'short', b'the', b'period', b'was', b'so', b'far', b'like', b'the', b'present', b'period', b'that', b'some', b'of', b'its', b'noisiest',b'authorities', b'insisted', b'on', b'its', b'being', b'received', b'for', b'good', b'or', b'for', b'evil', b'in', b'the', b'superlative', b'degree', b'of', b'comparison', b'only']
在 REPL 上进行这种探索性编程对于 Python 来说非常常见,因为它允许我们在决定使用代码位之前先了解代码位的作用。在这种情况下,请注意,每个单引号中的单词都有一个小写字母b
作为前缀,这意味着我们有一个bytes
对象列表,而我们更希望有一个str
对象列表。这是因为HTTP
请求通过网络将原始字节传输给我们。
要获得字符串列表,我们应该将 UTF-8 中每行的字节流解码为 Unicode 字符串。我们可以通过插入对bytes
对象的decode()
方法的调用,然后对生成的 Unicode 字符串进行操作来实现这一点。Python REPL 支持简单的命令历史记录,通过小心地使用向上和向下箭头键,我们可以重新输入代码片段,尽管不需要重新导入urlopen
,因此我们可以跳过第一行:
>>> with urlopen('http://sixty-north.com/c/t.txt') as story:
… story_words = []
… for line in story:
… line_words = line.decode('utf-8').split()
… for word in line_words:
… story_words.append(word)
…
这是我们已经更改的第四行–当您到达命令历史记录的该部分时,您可以使用左箭头键和右箭头键编辑它,以插入对decode()
的必要调用。当我们重新运行块并重新查看story_words
时,我们应该看到我们有一个字符串列表:
>>> story_words
['It', 'was', 'the', 'best', 'of', 'times', 'it',
'was', 'the', 'worst', 'of', 'times', 'it', 'was', 'the', 'age', 'of',
'wisdom', 'it', 'was', 'the', 'age', 'of', 'foolishness', 'it', 'was',
'the', 'epoch', 'of', 'belief', 'it', 'was', 'the', 'epoch', 'of',
'incredulity', 'it', 'was', 'the', 'season', 'of', 'Light', 'it',
'was', 'the', 'season', 'of', 'Darkness', 'it', 'was', 'the',
'spring', 'of', 'hope', 'it', 'was', 'the', 'winter', 'of', 'despair',
'we', 'had', 'everything', 'before', 'us', 'we', 'had', 'nothing',
'before', 'us', 'we', 'were', 'all', 'going', 'direct', 'to',
'Heaven', 'we', 'were', 'all', 'going', 'direct', 'the', 'other',
'way', 'in', 'short', 'the', 'period', 'was', 'so', 'far', 'like',
'the', 'present', 'period', 'that', 'some', 'of', 'its', 'noisiest',
'authorities', 'insisted', 'on', 'its', 'being', 'received', 'for',
'good', 'or', 'for', 'evil', 'in', 'the', 'superlative', 'degree',
'of', 'comparison', 'only']
我们已经达到了在 Python REPL 中输入和修改代码的极限,因此在下一章中,我们将研究如何将此代码移动到一个文件中,以便在文本编辑器中更轻松地使用它。
-
str
Unicode 字符串和bytes
字符串:-
我们研究了用于引用字符串的各种形式的引号(单引号或双引号),这对于将引号本身合并到字符串中非常有用。Python 可以灵活地使用引用样式,但在分隔特定字符串时必须保持一致。
-
我们证明了所谓的三重引号,由三个连续的引号字符组成,可以用来分隔多行字符串。传统上,每个引号字符本身就是双引号,尽管也可以使用单引号。
-
我们看到了相邻字符串文本是如何隐式连接的。
-
Python 支持通用换行符,因此无论您使用哪种平台 ,只要使用一个
\n
字符就足够了,在 知识中是安全的,它将在 I/O 期间适当地从本机 换行符转换为本机 换行符。 -
转义序列提供了一种将换行符和其他控制字符合并到文本字符串中的替代方法。
-
用于转义的反斜杠可能会妨碍 Windows 文件系统路径或正则表达式,因此可以使用带有
r
前缀的原始字符串来抑制转义机制。 -
其他类型,例如整数,可以使用
str()
构造函数转换为字符串。 -
单个字符作为一个字符串返回,可以使用带整数零索引的方括号进行检索。
-
字符串通过其方法支持多种操作,例如拆分。
-
在 Python3 中,文本字符串可以直接在源代码中包含任何 Unicode 字符,默认情况下将其解释为 UTF-8。
-
bytes
类型具有字符串的许多功能,但它是一个 序列作为bytes
而不是一个 Unicode 码点序列。 -
bytes
文本的前缀为小写的b
。 -
要在字符串和字节实例之间进行转换,我们使用
str
的encode()
方法或bytes
的decode()
方法,在这两种情况下都传递编解码器的名称,这是我们必须事先知道的。
-
-
list
文字-
列表是可变的、异构的对象序列。
-
列表文字由方括号分隔,项目由逗号分隔。
-
单个元素可以通过索引到带有方括号的列表中来检索,该列表包含一个从零开始的整数索引。
-
与字符串不同,单个列表元素可以通过分配给索引项来替换。
-
列表可以通过
append()
扩展到它们,并且可以使用list()
构造函数从其他序列构造列表。
-
-
dict
-
字典将键与值相关联。
-
文字词典由大括号分隔。键-值对之间用逗号分隔,每个键用冒号与其对应的值相关联。
-
-
for
循环-
for
-循环从iterable
对象(如列表)中逐个获取项目,并将相同名称绑定到当前项目。 -
它们对应于所谓的
for
——每个循环都使用其他语言。
-
在这本书中,我们不涉及正则表达式——也称为正则表达式。有关更多信息,请参阅 Python 标准库re
模块的文档。https://docs.python.org/3/library/re.html 。