处理字符数据是编程不可或缺的一部分。Python 提供了一组丰富的运算符、函数和方法来处理字符串,包括字符串运算符、内置函数、索引、切片和内置方法。
整套学习自学教程中应用的数据都是《三國志》、《真·三國無雙》系列游戏中的内容。
字符串操作
字符串 运算符
用于连接字符串,返回一个由连接在一起的操作数组成的字符串。
a = '劉備'
b = '関羽'
c = '張飛'
a b c
'劉備関羽張飛'
* 运算符创建字符串的多个副本。返回一个整数 n 个 s 字符串连接组成的字符串。
s = '劉備'
s * 4
'劉備劉備劉備劉備'
4 * s
'劉備劉備劉備劉備'
乘数操作数n必须是正整数。
字符串 in 运算符Python 提供了一个可以与字符串一起使用的成员运算符。如果第一个操作数包含在第二个操作数中,则 in 运算符返回 True 否则返回 False 。
s = '劉備'
s in '劉備(公元161年-公元223年6月10日),字玄德'
True
not in 用于相反的处理操作运算符。
s not in '劉備(公元161年-公元223年6月10日),字玄德'
False
Python 提供了许多内置于解释器并且始终可用的函数。
功能 |
描述 |
ord(s),将所有信息存储为数字,使用了一种将每个字符映射到其代表的数字,返回 character 的 ASCII 值。
ord('劉')
21129
ord('備')
20633
chr(n),做的是ord()相反的事情,给定一个数值n,返回一个字符串 ,用于处理处理 Unicode 字符。
chr(21129)
'劉'
chr(20633)
'備'
len(s),返回字符串的长度。
s = '三國無双'
len(s)
4
str(obj),返回对象的字符串表示形式,任何对象都可以强制转换字符串。
str(116)
'116'
str(1 2j)
'(1 2j)'
str(1 1)
'2'
str('三國無双')
'三國無双'
在 Python 中字符串是字符数据的有序序列,因此可以进行索引操作。通过指定字符串名称后跟方括号 ( [] ) 用数字来访问字符串中的各个字符。
Python 中的字符串索引是从零开始的。
s = '三國無双'
# 正索引
s[0]
'三'
s[1]
'國'
len(s)
4
s[len(s)-1]
'双'
# 负索引
s[-1]
'双'
s[-2]
'無'
len(s)
4
s[-len(s)]
'三'
尝试超出字符串末尾的索引会导致错误。
# 正索引
s[5]
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
s[5]
IndexError: string index out of range
# 负索引
s[-6]
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
s[-6]
IndexError: string index out of range
Python 允许一种从字符串中提取的字符串的索引语法形式称为字符串切片。如果 s 是字符串形式的表达式返回以 s[m:n] 的部分。
s = '三國無双'
s[2:4]
'無双'
省略搜索引切片从字符串的开头开始,s[:m] 等价 s[0:m] 。
s = '三國無双'
s[:2]
'三國'
s[0:2]
'三國'
省略第二个索引切片字符串的位置 n 到结束,s[n:] 等价 s[n:len(s)] 。
s = '三國無双'
s[2:]
'無双'
s[2:len(s)]
'無双'
对于任何字符串 s 和任何整数 n( 0 ≤ n ≤ len(s)),s[:n] s[n:]等于s。
s = '三國無双'
s[:2] s[2:]
'三國無双'
s[:2] s[2:] == s
True
省略两个索引会返回完整的原始字符串。
s = '三國無双'
t = s[:]
id(s)
2415970797232
id(t)
2415970797232
s is t
True
对于 string 『三國無双』
- 切片 0:4:2 从第一个字符开始,到最后一个字符(整个字符串)结束,并且每隔一个字符被跳过。
- 切片 1:6:2 从第二个字符(索引1)开始并以最后一个字符结束的切片,并且步幅值再次2导致每隔一个字符被跳过。
s = '三國無双'
s[0:4:2]
'三無'
s[1:6:2]
'國双'
省略第一、第二索引,并分别默认为第一和最后一字符。
s = '三國無双' * 5
s
'三國無双三國無双三國無双三國無双三國無双'
s[::4]
'三三三三三'
s[3::4]
'双双双双双'
指定一个负的步幅值会向后遍历字符串,第一个索引应该大于结束第二个索引。
s = '三國無双'
s[4:0:-2]
'双國'
f-strings 提供的格式化功能非常广泛,用于显示算术计算的结果。可以用一个简单的 print() 语句来做到这一点,用逗号分隔数值和字符串文字。
wei = 23
wu = 21
sum_ = wei wu
print('魏', wei, '人和呉', wu, '一共', sum_,'人。')
魏 23 人和呉 21 一共 44 人。
使用 f-string 重铸,上面的示例看起来更清晰。
wei = 23
wu = 21
sum_ = wei wu
print(f'魏 {wei} 人和呉 {wu} 一共 {sum_} 人。')
魏 23 人和呉 21 一共 44 人。
Python 的三种引用机制中的任何一种都可用于定义 f 字符串。
var = '马孟起'
print(f'この{var}が相手だ!')
この马孟起が相手だ!
print(f"この{var}が相手だ!")
この马孟起が相手だ!
print(f'''この{var}が相手だ!''')
この马孟起が相手だ!
字符串是 Python 认为不可变的数据类型之一,修改会导致错误。
s = '三國無双'
s[3] = 'x'
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
s[3] = 'x'
TypeError: 'str' object does not support item assignment
可以通过生成具有所需更改的原始字符串的副本来轻松完成所需的操作。
s = s[:2] 'x' s[1:]
s
'三國x國無双'
可以使用内置的字符串方法完成修改操作。
s = '三國無双'
s = s.replace('國', 'x')
s
'三x無双'
Python 程序中的每一项数据都是一个对象,使用 dir 方法会返回一个内置方法与属性列表。方法类似于函数,与对象紧密关联的一种特殊类型的可调用过程。
dir('a,b,cdefg')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
目标字符串执行大小写转换应用举例
s.capitalize(),返回第一个字符转换为大写,所有其他字符转换为小写的副本,非字母字符不会改变操作方式。
s = 'Dynasty Warriors'
s.capitalize()
'Dynasty warriors'
s = 'Dynasty123#warriors'
s.capitalize()
'Dynasty123#warriors'
s.lower(),返回所有字母字符都转换为小写的副本。
'Dynasty Warriors'.lower()
'dynasty warriors'
s.swapcase(),返回将大写字母字符转换为小写字母的副本,s 反之亦然。
'Dynasty Warriors'.swapcase()
'dYNASTY wARRIORS'
s.title(),每个单词的第一个字母转换为大写,其余字母为小写。
'dynasty warriors'.title()
'Dynasty Warriors'
s.upper(),返回所有字母字符都转换为大写的副本
'Dynasty Warriors'.upper()
'DYNASTY WARRIORS'
查找和替换方法应用举例。
s.count(<sub>,[<start>,<end>]),返回计算目标字符串中子字符串的出现次数。
# 非重叠出现的 <sub> 次数
'三國無双 三國無双 三國無双 三國'.count('三國無双')
3
# 指定切片位置
'三國無双 三國無双 三國無双 三國'.count('三國無双', 0, 8)
1
s.endswith(<suffix>,[<start>,<end>]) ,返回目标字符串是否以给定的子字符串结尾。
'三國無双'.endswith('無双')
True
'三國無双'.endswith('三國')
False
# 指定切片位置
'三國無双'.endswith('國無', 1, 3)
True
'三國無双'.endswith('國無', 2, 4)
False
s.find(<sub>,[<start>,<end>]),返回找到子字符串s.find(<sub>)的索引。
'無双 三國無双 三國'.find('三國')
3
# 如果未找到指定的子字符串,则此方法返回-1
'無双 三國無双 三國'.find('大喬')
-1
# 指定切片位置
'三國無双 三國無双 三國無双 三國無双'.find('三國無双', 4)
5
'三國無双 三國無双 三國無双 三國無双'.find('三双', 4, 7)
-1
s.index(<sub>,[<start>,<end>]), 在目标字符串中搜索给定的子字符串索引。
'三國無双 三國無双 三國無双 三國無双'.index('三國')
0
# 和find相同,但是未找到会引发异常
'三國無双 三國無双 三國無双 三國無双'.index('三双')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
s.rfind(<sub>,[<start>,<end>]),返回找到子字符串的最高(最右侧)索引。
'三國無双 三國無双 三國無双 三國無双'.rfind('無双')
17
# 未找到子字符串则返回-1
'三國無双 三國無双 三國無双 三國無双'.rfind('三双')
-1
# 指定切片位置
'三國無双 三國無双 三國無双 三國無双'.rfind('無双', 0, 14)
12
'三國無双 三國無双 三國無双 三國無双'.rfind('無双', 10, 14)
-1
s.rindex(<sub>,[<start>,<end>]),从末尾开始搜索给定子字符串的目标字符串**
'三國無双 三國無双 三國無双 三國無双'.rindex('國無')
16
# 和rfind相同,但是未找到会引发异常
'三國無双 三國無双 三國無双 三國無双'.rindex('三双')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
**s.startswith(,[,])**,返回判断是否以字符串开头的结果。
'三國無双'.startswith('三國')
True
'三國無双'.startswith('無双')
False
# 指定切片位置
'三國無双'.startswith('國',1)
True
'三國無双'.startswith('無',2,3)
True
字符分类方法应用举例。
s.isalnum(),返回目标字符串是否由字母、数字、字符组成。
'三國無双123'.isalnum()
True
'三國無双#123'.isalnum()
False
''.isalnum()
False
s.isalpha(),返回目标字符串是否由字母字符组成。
'ASD'.isalpha()
True
'三國無双ASD'.isalpha()
False
s.isdigit(),返回目标字符串是否由数字字符组成。
'123'.isdigit()
True
'三國無双123'.isdigit()
False
s.isidentifier(),返定目标字符串是否是有效的 Python 标识符(变量名)。
'三國無双123'.isidentifier()
True
'12三國無双'.isidentifier()
False
'三國無双$12'.isidentifier()
False
s.islower(),返回目标字符串的字母字符是否为小写。
'abc'.islower()
True
'abc1$d'.islower()
True
'Abc1$三國無双'.islower()
False
s.isprintable(),返回目标字符串是否完全由可打印字符组成。
'三國\t無双'.isprintable()
False
'三國 無双'.isprintable()
True
''.isprintable()
True
s.isspace(),返回目标字符串是否由空白(不可见)字符组成。
' \t \n '.isspace()
True
' 三國無双 '.isspace()
False
# ASCII 字符可以作为空格
'\f\u2005\r'.isspace()
True
s.istitle(),返回目标字符串是否为标题大小写格式。
'Dynasty Warriors'.istitle()
True
'Dynasty warriors'.istitle()
False
s.isupper(),返回目标字符串的字母字符是否为大写格式。
'DYNASTY WARRIORS'.isupper()
True
'Dynasty$WARRIORS'.isupper()
True
'Dynasty$Warriors'.isupper()
False
字符串格式方法应用举例。
s.center(<width>,[<fill>]),返回一个由以宽度 <width> 为中心的字段组成的字符串。
'三國無双'.center(10)
' 三國無双 '
# 指定填充字符
'三國無双'.center(10, '-')
'---三國無双---'
# 字符长度小于指定返回原字符
'三國無双'.center(2)
'三國無双'
s.expandtabs(tabsize=8),对字符串中的制表符使用空格进行替换。
'三國\t無双'.expandtabs()
'三國 無双'
# tabsize指定备用制表位列
'三國\t無双'.expandtabs(4)
'三國 無双'
**s.ljust(,[])**,返回一个由宽度为左对齐的字段组成的字符串。
'三國無双'.ljust(10)
'三國無双 '
# 指定填充字符
'三國無双'.ljust(10, '-')
'三國無双------'
# 字符长度小于指定返回原字符
'三國無双'.ljust(2)
'三國無双'
s.lstrip([<chars>]),返回从左端删除任何空白字符的副本。
' 三國無双 三國無双 '.lstrip()
'三國無双 三國無双 '
'\t\n三國無双\t\n三國無双\t\n'.lstrip()
'三國無双\t\n三國無双\t\n'
# 指定删除字符集
'.$$$;三國無双.$$$;'.lstrip(';$.')
'三國無双.$$$;'
s.replace(<old>, <new>[, <count>]), 返回所有出现的子字符串替换为s.replace(<old>, <new>)的副本。
'_三國無双 _三國無双'.replace('_', '真・')
'真・三國無双 真・三國無双'
# <count>参数指定替换数
'_三國無双 _三國無双'.replace('_', '真・',1)
'真・三國無双 _三國無双'
s.rjust(<width>, [<fill>]),返回一个由宽度<width>字段右对齐组成的字符串。
'三國無双'.rjust(10)
' 三國無双'
# 指定填充字符
'三國無双'.rjust(10, '-')
'------三國無双'
# 字符长度小于指定返回原字符
'三國無双'.rjust(2)
'三國無双'
s.rstrip([<chars>]),返回从右端删除任何空白字符的副本。
' 三國無双 三國無双 '.rstrip()
' 三國無双 三國無双'
'三國無双\t\n三國無双\t\n'.rstrip()
'三國無双\t\n三國無双'
# 指定删除字符集
'.$$$;三國無双.$$$;'.rstrip(';$.')
'.$$$;三國無双'
s.strip([<chars>]),返回同时调用 .lstrip() 和 .rstrip() 的副本。
s = ' 三國無双 三國無双 \t\t\t'
s_ = s.lstrip().rstrip()
s_
'三國無双 三國無双'
s.strip()
'三國無双 三國無双'
# 指定删除字符集
'三國無双'.strip('無双')
'三國'
'三國無双'.replace('無双','')
'三國'
s.zfill(<width>),返回用数字 0 填充的指定<width>字符的副本。
'三國無双'.zfill(5)
'0三國無双'
# 如果包含符号仍保留
' 0三國無双'.zfill(8)
' 000三國無双'
# 字符长度小于指定返回原字符
' 三國無双'.zfill(3)
' 三國無双'
顺序集合 iterables 字符串和列表之间的转换方法应用举例。
s.join(<iterable>),返回由分隔的对象连接得到的字符串。
', '.join(['大喬', '小喬', '孫尚香', '練師'])
'大喬, 小喬, 孫尚香, 練師'
# 字符串的操作
list('三國無双')
['三', '國', '無', '双']
'/'.join('三國無双')
'三/國/無/双'
# list中的数据必须是字符串
'-'.join(['三國', 1, '無双'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence item 1: expected str instance, int found
'-'.join(['三國', str(1), '無双'])
'三國-1-無双'
s.partition(<sep>),返回值是一个由<sep>前、<sep>本身、<sep>后三部分组成的元组。
'三國.無双'.partition('.')
('三國', '.', '無双')
'真@@三國@@無双'.partition('@@')
('真', '@@', '三國@@無双')
# 如果未找到则返回2个空字符
'三國.無双'.partition('@@')
('三國.無双', '', '')
s.rpartition(<sep>),与s.partition(<sep>)相同,用于指定最后一次字符串拆分符。
'真@@三國@@無双'.partition('@@')
('真', '@@', '三國@@無双')
'真@@三國@@無双'.rpartition('@@')
('真@@三國', '@@', '無双')
s.rsplit(sep=None, maxsplit=-1),返回拆分为由任何空格序列分隔的子字符串,并将子字符串作为列表。
'真 三國 無双'.rsplit()
['真', '三國', '無双']
'真\n\t三國 三國\r\f無双'.rsplit()
['真', '三國', '三國', '無双']
# 指定拆分符
'真.三國.無双'.rsplit(sep='.')
['真', '三國', '無双']
'真.三國.無双'.rsplit('.')
['真', '三國', '無双']
# 指定最多拆分次数
'真.三國.無双'.rsplit(sep='.', maxsplit=1)
['真.三國', '無双']
'真.三國.無双'.rsplit(sep='.', maxsplit=-1)
['真', '三國', '無双']
'真.三國.無双'.rsplit(sep='.')
['真', '三國', '無双']
s.split(sep=None, maxsplit=-1),返回拆分为子字符串列表。指定<maxsplit> 计算拆分次数。
'真.三國.無双'.split('.', maxsplit=1)
['真', '三國.無双']
'真.三國.無双'.rsplit('.', maxsplit=1)
['真.三國', '無双']
s.splitlines([<keepends>]),返回换行符切分的列表,其中包含\n、\r、\r\n、\v or \x0b、\f or \x0c、\x1c、\x1d、\x1e、\x85、\u2028、\u2029。
'真\n三國\r\n無双\f三國\u2028無双'.splitlines()
['真', '三國', '無双', '三國', '無双']
# 保留行边界符号
'真\n三國\r\n無双\f三國\u2028無双'.splitlines(True)
['真\n', '三國\r\n', '無双\x0c', '三國\u2028', '無双']
'真\n三國\r\n無双\f三國\u2028無双'.splitlines(1)
['真\n', '三國\r\n', '無双\x0c', '三國\u2028', '無双']
对象是操作二进制数据的bytes核心内置类型之一,bytes对象是不可变的单字节值序列。
定义文字bytes对象
文字的bytes定义方式与添加 'b' 前缀的字符串文字相同。
b = b'Dynasty Warriors'
b
b'Dynasty Warriors'
type(b)
<class 'bytes'>
可以使用任何单引号、双引号或三引号机制。
b'Dynasty Warriors'
b"Dynasty Warriors"
b'''Dynasty Warriors'''
'r' 前缀可以用在文字上以禁用转义序列的bytes处理。
b = rb'Dynasty\Warriors'
b
b'Dynasty\\Warriors'
b[9]
97
chr(97)
'a'
bytes()函数还创建一个bytes对象,返回对象取决于传递给函数的参数。
bytes(<s>, <encoding>),根据指定的使用将字符串转换<s>为bytes对象。
b = bytes('Dynasty.Warriors', 'utf8')
b
b'Dynasty.Warriors'
type(b)
<class 'bytes'>
bytes(<size>),创建一个bytes由 null (0x00) 字节组成的对象。
# bytes指定的对象<size>必须是一个正整数。
b = bytes(8)
b
b'\x00\x00\x00\x00\x00\x00\x00\x00'
type(b)
<class 'bytes'>
bytes(),从可迭代对象创建对象生成的整数序列中定义一个对象<iterable> n0 ≤ n ≤ 255。
b = bytes([100, 101, 102, 103, 104])
b
b'defgh'
type(b)
<class 'bytes'>
运算符 in 和 not in
b = b'abcde'
b'cd' in b
True
b'o' not in b
True
连接 ( ) 和复制 ( *) 运算符
b = b'abcde'
b b'fghi'
b'abcdefghi'
b * 3
b'abcdeabcdeabcde'
索引和切片
b = b'abcde'
b[2]
99
b[1:3]
b'bc'
内置功能,功能参考字符串操作其他功能,不支持中文。
b = b'Dynasty\nWarriors'
len(b)
16
min(b)
10
max(b)
121
bytes.fromhex(<s>),返回bytes将每对十六进制数字转换<s>为相应字节值的对象。
b = bytes.fromhex(' aa 68 4682cc ')
b
b'\xaahF\x82\xcc'
list(b)
[170, 104, 70, 130, 204]
b.hex() bytes从对象返回一串十六进制值
# 将bytes对象b转换为十六进制数字对字符串的结果,与.fromhex()相反
b = bytes.fromhex(' aa 68 4682cc ')
b
b'\xaahF\x82\xcc'
b.hex()
'aa684682cc'
type(b.hex())
<class 'str'>
bytearray始终使用内置函数创建对象bytearray()
ba = bytearray('真.三國.無双', 'UTF-8')
ba
bytearray(b'\xe7\x9c\x9f.\xe4\xb8\x89\xe5\x9c\x8b.\xe7\x84\xa1\xe5\x8f\x8c')
bytearray(6)
bytearray(b'\x00\x00\x00\x00\x00\x00')
bytearray([100, 102, 104, 106, 108])
bytearray(b'dfhjl')
bytearray对象可变,使用索引和切片修改对象的内容。
ba = bytearray('真.三國.無双', 'UTF-8')
ba
bytearray(b'\xe7\x9c\x9f.\xe4\xb8\x89\xe5\x9c\x8b.\xe7\x84\xa1\xe5\x8f\x8c')
ba[5] = 0xee
ba
bytearray(b'\xe7\x9c\x9f.\xe4\xee\x89\xe5\x9c\x8b.\xe7\x84\xa1\xe5\x8f\x8c')
ba[8:11] = b'hello'
ba
bytearray(b'\xe7\x9c\x9f.\xe4\xee\x89\xe5hello\xe7\x84\xa1\xe5\x8f\x8c')
bytearray对象,直接从对象构造bytes。
ba = bytearray(b'Dynasty Warriors')
ba
bytearray(b'Dynasty Warriors')