字符串

Python 中的字符串可以使用单引号或者双引号来创建,使用单引号和双引号创建的字符串没有区别。Python 中没有单字符类型,即便是一个字符,也是作为一个字符串使用。字符串支持使用切片来截取其子字符串,切片的使用方法可见“切片”一节。

Python 中的字符串是不可变数据,每次在进行运算时,都会产生一个新的字符串对象,如果使用id()函数去获取他们的内存地址就会发现变量的指向地址始终在变化。

字符串支持下表中的运算符进行运算。

操作符功能
+连接字符串
\*重复输出字符串
[]通过索引获取字符串中的字符
[:]通过切片获取字符串中的一部分
in成员运算符,测试字符串中是否包含指定字符
not in成员运算符,测试字符串中是否不包含指定字符
r原始字符串标记,例如r"Hello\n"将原封不动的输出,不转换任何转义字符
b字节标记,将str变为以字节为单位的bytes
uUTF-8 字符串标记,用于标记字符串内容为 UTF-8 编码,例如u"你好",Python3 中所有的字符串都是 UTF-8 的,这个标记已经不再需要了。
f格式化字符串标记,允许将变量及表达式等直接插入字符串形成字符串常量。
%格式化输出字符串

由于 Python3 的字符串类型为str,在内存中以 Unicode 表示,一个字符对应若干个字节,所以要在网络上传输或者保存到磁盘,就需要将其转换为以字节为单位的bytes,这可以使用b在字符串前进行标记,例如:b'ABC'。中文内容不能用 ASCII 编码表示,但是可以将含有中文的str编码为bytes

Python 中还允许使用三引号"""来包裹字符串,三引号定义的字符串可以跨多行,并且可以包含换行、制表等特殊字符。三引号字符串可以自行保持字符串的原有格式,每行的换行符以及行首、行尾的空格都会保留,使日常编程不再需要字符串组合与转义等。

使用str()可以将其他数据类型转换为字符串。在使用print()或者字符串差值是,Python 都会自动使用str()对非字符串对象进行转换。

在字符串名后面添加[],并在括号中指定索引,可以提取指定索引位置的单个字符,字符串的索引值从 0 开始。索引值可以是负数,这代表从字符串尾端开始。如果对指定索引位置进行赋值,则会得到TypeError错误,因为字符串是不可变的。如果需要改变字符串,需要使用字符串函数或者切片来完成,这些将在后面具体提到。

字符串格式化

Python 中的字符串格式化使用与 C 语言中printf()一样的语法,其基本思路是将一个值或者数个值插入到一个有字符串格式描述符的字符串中。

例如:

print("这是来自%d 光年外%s 的信息。" % (3000, "St. Alpha"))

# 会输出“这是来自 3000 光年外 St. Alpha 的信息。”

字符串格式化通过一系列的格式化符号对要替换的内容进行标记,常用的格式化符号见下表。

符号功能
%c输出字符及其 ASCII 码
%s输出字符串
%d输出整数
%u输出无符号整数
%o输出无符号八进制整数
%x输出无符号小写十六进制整数
%X输出无符号大写十六进制整数
%f输出浮点数,可搭配辅助指令指定小数精度
%e%E使用科学计数法输出浮点数
%g%G根据浮点数长度自动选择自然计数法或者科学计数法输出浮点数
%p用十六进制输出变量的地址

格式化符号可以接受一些辅助指令的来对输出内容的格式进行详细规定。常用的辅助指令见下表。

符号功能示例
*接受一个整型值,定义显示宽度,可以直接书写整型值'%*s' % (10, 'Willie')
-左对齐'%-*s' % (10, 'Willie')
+强制显示正负号'%+d' % 10
空格在正数前显示空格'% d' % 10
#显示八进制、十六进制前的引导标记(0o}或者0x})'%#x' % 90
0在数字前填充 0 而不是空格'%0*d' % (8, 10)
%输出一个单一的%
(var)从字典参数中获取相应键值的值'%(a)d' % {'a':90}
m.n.m 为显示的最小总宽度(可省略),n 是小数点后的位数'%10.5f' % 19.093

自从 Python 2.6 版本开始,字符串提供了str.format()函数来进行增强的字符串格式化功能,调用格式为"模版字符串".format(逗号分割的参数)。调用format()方法后会返回一个全新的字符串。模版字符串中使用{}来代表参数,称为格式槽,参数从 0 开始索引,例如:"进程{}的 CPU 占用率为{}%。".format("Python", 10)会输出"进程 Python 的 CPU 占用率为 10%。"。如果需要引用指定索引的参数,可以在{}中书写指定参数的索引,例如例如:"进程{1}的 CPU 占用率为{0}%。".format(10, "Python")会输出"进程 Python 的 CPU 占用率为 10%。"。若要输出大括号,可以使用{{表示{,用}}表示}

format()方法中同样可以控制参数的格式,其中格式槽的格式为{<参数序号>:<填充><对齐><宽度><,><.精度><类别>}。各个格式位的使用方法可参考下表。

:<填充><对齐><宽度><,><.精度><类别>
用于填充的单个字符<,左对齐槽的设定输出宽度数字千分位分隔符浮点数小数点部分的精度b,二进制整型
>,右对齐字符串的最大输出长度c,Unicode 字符
^,居中d,十进制整数
o,八进制整数
X,大写十六进制整数
E,大写指数形式浮点数
%,百分比形式浮点数

例如"{0:e},{0:0.4f}".format(3.14),读者可自行在交互式解释器中实验以下这条语句的运行结果。

自 Python 3.6 版本开始,Python 基金会通过 PEP 498 – Literal String Interpolation 引入了格式化字符常量来产生一个格式化后的字符串,因为这种用法是采用f""的字符串标记形式,所以又称为“f-string”。f-string 的功能与之前介绍的使用“%”进行格式化和使用str.format()进行格式化的功能基本相同,但具有更好的性能,所以如果要使用 Python 3.6 以后的版本,推荐使用 f-string 来进行字符串格式化。

f-string 在字符串中使用{}来直接填入替换内容,并且其中支持表达式和函数调用。最简单的使用方法可见一下示例。

number = 7
print(f"Total number is {number}")

print(f"Calculate result is {(2 + 4j) / (2 - 3j)}")

name = "ERIC"
print(f"The lowercase version is {name.lower()}")

f-string 在使用时也是有一些限制要求的,主要集中在符号的使用上,限制条件主要有以下几个。

  1. 大括号内所使用的引号不能与大括号外的字符串定界符冲突,例如|f“{“ERIC”}“|是错误的。
  2. 如果单引号和双引号不能满足要求,可以使用三引号来定义字符串,例如|f““”{“Eric”}“”“|。
  3. 大括号外的引号可以使用||进行转义,但大括号内不可以。
  4. 如果在大括号外要显示大括号,需要使用|{{|和|}}|的形式。

f-string 也支持格式描述,其使用格式为{内容:格式},例如f"{number:8.2f}"。f-string 的格式描述符格式与str.format()基本相同,但是其更扩展支持了 datetime 库中用于格式化时间的描述符,具体内容可在使用时参考 datetime 库文档。

Warning

在 Python 3.8 中为 f-string 增加了一个=说明符。f"{expr=}"将被输出为赋值表达式的文本。

内建函数

对于字符串操作,Python 提供了以下常用函数。

  • capitalize(),将字符串第一个字符转换位大写。
  • center(width, fillchar),返回一个指定宽度为 width 并居中的字符串,字符串两端使用 fillchar 填充,默认使用空格。
  • count(str, begin=0, end=len(string)),返回 str 在字符串中出现的次数,其中 begin 和 end 用于指定进行统计的字符串范围。
  • bytes.decode(encoding='utf-8', errors='strict'),Python3 中的字符串没有 decode 方法,所以需要使用bytes模块中的decode()方法来解码 bytes 对象。
  • encode(encoding='UF-8', errors='strict'),以指定编码格式编码字符串,如果出错则报ValueError的异常,除非errors的值为'ignore'或者'replace'
  • endswith(suffix, begin=0, end=len(string)),检查字符串是否以suffix结束,如果指定beginend的值,则检查指定范围。返回布尔型值。
  • expandtabs(tabsize=8),将字符串中的 tab 符号转换为空格,默认一个 tab 转换为 8 个空格。
  • find(str, begin=0, end=len(string)),检查str是否包含在字符串中,如果指定beginend的值,则检查指定范围。返回布尔型值。
  • index(str, begin=0, end=len(string)),获取str在字符串中的索引位置,如果字符串中不存在str则报异常。
  • isalnum(),如果字符串至少有一个字符且全部都是字符或者数字,返回True
  • isaloha(),如果字符串至少有一个字符且全部都是字符,返回True
  • isdigit(),如果字符串至少有一个字符且全部都是数字,返回True
  • islower(),如果字符串中包含至少一个区分大小写的字符,且全部都是小写,返回True
  • isnumeric(),如果字符串只包含数字字符,返回True
  • isspace(),如果字符串只包含空白,返回True
  • istitle(),如果字符串是标题化的,返回True
  • isupper(),如果字符串中包含至少一个区分大小写的字符,且全部都是大写,返回True
  • join(seq),以指定字符串为分隔符,将seq中的所有元素合并为一个新的字符串。
  • len(string),返回字符串长度。
  • ljust(width[, fillchar]),返回一个宽度为width的字符串,原字符串在新字符串中左对齐,右侧用fillchar填充。
  • lower(),将所有字符转为小写。
  • lstrip(),截掉字符串左边的空格或者指定字符。
  • maketrans(),创建字符映射的转换表。
  • max(str),返回字符串str中最大的字母。
  • min(str),返回字符串str中最小的字母。
  • replace(old, new[, max]),将字符串中的old替换成new,替换不超过max次。
  • rfind(str, begin=0, end=len(string)),从右侧查找。
  • rindex(str, begin=0, end=len(string)),从右侧获取索引。
  • rjust(width[, fillchar]),返回一个宽度为width的字符串,原字符串在新字符串中右对齐,左侧用fillchar填充。
  • rstrip(),删除字符串末尾的空格。
  • split(str='', num=string.count(str)),以str为分隔符截取字符串,截取num个子字符串。
  • splitlines([keepends]),按照'\r''\r\n''\n'为分割,返回包含各行作为元素的列表。如果keependsFalse则不包含换行符。
  • startswith(prefix, begin=0, end=len(string)),检查字符串是否以prefix结束,如果指定beginend的值,则检查指定范围。返回布尔型值。
  • strip([chars]),在字符串上执行lstrip()rstrip()
  • swapcase(),将字符串中的大小写反转。
  • title(),返回标题化字符串,即每个单词都是大写开始,其余字母均为小写。
  • translate(table, deletechars=''),根据table给出的表,转换字符串,要过滤掉deletechars中的字符。
  • upper(),转换字符串中的字母为大写。
  • zfill(width),返回长度为width的字符串,原字符串右对齐,左侧填充 0。
  • isdecimal(),检查字符串中是否只包含十进制字符。