本节书摘来自华章计算机《从问题到程序:用Python学编程和计算》一书中的第2章,第2.4节,作者 裘宗燕,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.4 字符串
文字处理是计算机的重要应用领域。此外,大多数计算机程序都需要和使用者打交道,需要接受使用者提供的数据或命令,给使用者提供反馈,把计算的结果展示给使用者,操作中也可能用到各种文字形式的信息。Python用字符串支持文本的表示和处理。
2.4.1 字符串和字符串类型
字符串就是字符的序列,Python中的字符串也是一种数据对象,其类型称为字符串类型,类型的名字是str。
字符串字面量
字符串有几种字面量描述形式,最简单的字面量是用一对单引号或者一对双引号括起的一系列字符(两种括号的作用相同,但要配对)。例如:
>>> 'University'
'University'
>>> "University"
'University'
>>> type('University')
<class 'str'>
CPython解释器输出字符串时都采用单引号括起的形式,这也间接说明,无论用单引号还是双引号写字符串字面量,结果都一样。这两种形式的限制是在一个字符串字面量中间不能换行,因此只适合描述比较短的字符串。如果在一个字符串没写完(没出现表示结束的第二个引号)时换行,解释器将报告语法错SyntaxError: EOL while scanning string literal,意为在扫描字符串字面量的过程中遇到了换行(EOL,end of line)。
字符串还有另外两种字面量形式。Python允许用一对连续的三个单引号或者一对连续的三个双引号作为字符串括号。这种形式的字符串,特点是描述中可以换行,换行符号也作为字符串内容。例如,下面是Python文档中的一段话:
>>> """Python is an interpreted, interactive,
object-oriented programming language. It
incorporates modules, exceptions, dynamic
typing, very high level dynamic data types,
and classes."""
'Python is an interpreted, interactive, \nobject-oriented programming language. It \nincorporates modules, exceptions, dynamic \ntyping, very high level dynamic data types, \nand classes.'
注意,这里的输入是连续的5行字符,解释器输出的是一个字符串,同样用一对单引号括起。比较输入和输出,可以看到输入中的每个换行,在解释器输出的字符串里变成了两个字符 n,实际上,这样两个字符的序列就表示一个换行字符。
特殊字符
有些字符无法用普通字符形式写出,上面的换行符就是一例。为了能在字符串里写这些字符,Python规定了一组特殊描述方式,其形式都是用一个反斜线字符开头,随后再写另外的字符。下面是几个常用特殊字符的写法及其解释:
这种写法称为换意序列,用反斜线符表示后面字符的意义换了。例如,如果想在单引号括起的字符串里写一个单引号,直接写出就表示字符串结束,显然不行。这里必须用换意序列,写两个字符“'”表示这个单引号。例如 'I don't think so'。其他情况类似。由于有两种引号,上例也可以简单写为 "I don't think so",这里就不必写反斜线符了。也就是说,在两个双引号括起的字符串里单引号是普通字符,反之依然。对反斜线符本身,如果单写就表示做换意,因此规定双写。本章语言细节一节列出了更多换意序列。
2.4.2 字符串操作
作为一种重要的数据类型,字符串也有很多操作。这里简单介绍几个最基本的字符串操作,更多操作将在后面介绍,另请查看Python标准库手册。
字符串运算
在一个字符串里包含一系列字符,其中每个字符有一个位置,从0开始顺序编号,称为下标(index)。可以通过编号取得字符串里对应的字符,例如:
>>> "University"[0]
'U'
>>> "University"[8]
't'
>>> "University"[10]
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
"University"[10]
IndexError: string index out of range
基于下标取字符串里的单个字符,用方括号里写下标的形式描述。显然,取字符只能在具体字符串的范围内进行,超范围访问是下标越界(index out of range)错误。Python允许用负整数作为下标提取字符串里的字符,下标 – 1表示取最后一个字符,其余类推:
>>> "University"[-3]
'i'
注意,Python语言里并没有独立的字符概念,只有字符串。通过下标取字符,得到的实际上是只包含一个字符的字符串。
字符串中的字符个数称为字符串的长度(length),用Python内置函数len可以求出字符串的长度,例如:
>>> len("University")
10
显然,对字符串s,其合法下标范围是0到len(s) – 1。
字符串的另一个重要操作是拼接,可以拼接起两个或更多个字符串,做出一个长字符串。Python中字符串的拼接用加法运算符表示。例如:
>>> "Peking" + " " + "University"
'Peking University'
实际中需要拼接的通常不是这种直接写出的字面量,而是程序里已有的字符串。注意,字符串拼接运算没有可交换性,交换两个运算对象,通常将得到另一字符串。
可以从一个字符串出发,做出它的几个拷贝的拼接,这种操作用乘法运算符描述。操作的另一运算对象应该用一个整数。例如:
"Ok!" * 3
'Ok!Ok!Ok!'
>>> 3 * "Ok!"
'Ok!Ok!Ok!'
两种顺序写的运算对象的效果完全一样。
字符串切片
切片是另一种重要字符串操作,其功效是取出已有字符串中的一部分(0个或多个字符),做成一个新字符串。字符串切片的描述方式与取字符类似,也用一对方括号。但括号里不是写一个表示整数的表达式,而是写一个切片描述。切片描述有两种不同形式。假设s是一个字符串,下面两种描述取得s的切片:
- s[m:n] 得到由字符s[m] 到s[n-1] 构成的字符串。如果m≥n就得到一个空字符串,其中不包含任何字符。
- s[m:n:d] 得到由s[m] 到s[n-1],下标的步进值为d选出字符做成的字符串。如果d是正数且m≥n,或者d是负数且n≥m,都得到空字符串。
这里的m、n、d都应该是值为整数的表达式,m或n的值为-1表示字符串s的最后一个字符,其余负数类推。切片描述中必须包含冒号,但m、n、d都可以省略。m省略时表示0(从字符串的首字符开始),n省略时表示len(s)(到最后一个字符为止),d省略时表示1。因此,对这两种使用形式,所有下标都省略时都表示做出整个字符串的拷贝。
注意,这里的下标范围描述采用左闭右开的规则,也就是说,总包含第一个下标描述的字符,但不包括第二个下标描述的字符,是一个左闭右开的字符位置区间。
下面是几个简单示例:
>>> "Universities in Beijing"[16:]
'Beijing'
>>> "Universities in Beijing"[:12]
'Universities'
>>> "Universities in Beijing"[::2]
'Uieste nBiig'
数值与字符串的转换
各种数值类型的对象都可以转换到字符串,得到它们的字符串表示。在程序输入输出时经常需要做这种转换,有些是自动完成的。先看几个例子:
>>> str(101)
'101'
>>> str(101) + str(2.3**4)
'10127.98409999999999'
最后一步做的是字符串拼接。后一个例子没有实际意义,只是为了说明问题。
同样可以做另一个方向的转换:如果一个字符串里的字符都是十进制数字(可以带正负号),可以从它转换得到一个整数或者浮点数:
>>> int("-1234")
-1234
>>> int("00011234")
11234
>>> float("00011234")
11234.0
开头的0自动忽略。此外,如果一个字符串的内容符合Python浮点数的要求,就可以从它构造出一个浮点数。例如:
>>> float("-256.38")
-256.38
>>> float("0.276e-3")
0.000276
字符串还有很多操作,将在第5章介绍,后面还会看到字符串的很多实际使用。