Python 字符串
10分钟阅读,如果有启发,欢迎评论关注点赞打赏
- 字符串方法
- 字符串切片
- 字符串格式
- 字符串百分比
- 字符串(Unicode 与字节)
- if 语句
- 练习:string1.py
Python 有一个名为“str”的内置字符串类,其中包含许多方便使用的功能(有一个名为“string”的较旧模块,您不应使用)。字符串字面量可以用双引号或单引号括起来,但单引号更为常用。反斜杠转义是单引号和双引号字面量的常规方式,例如 \n \" 。双引号字符串字面量可以包含单引号,并且无需任何麻烦(例如“我没有这样做”),同样的单引号字符串也可以包含双引号。字符串字面量可以跨多行,但每行的末尾必须有一个反斜杠 \ 以转义换行符。三引号中的字符串字面量“"”或“'”可以跨多行文本。
Python 字符串是“不可变”的,这意味着这些字符串在创建后无法更改(Java 字符串也使用此不可变样式)。由于字符串无法更改,因此我们构建 *新* 字符串以表示计算值。例如,表达式“hello”+“there”接受“hello”和“there”这两个字符串,并构建一个新的字符串“hellothere”。
可以使用标准 [ ] 语法访问字符串中的字符;与 Java 和 C++ 一样,Python 使用从 0 开始的索引;如果 s 为“hello”,s[1] 为“e”。如果索引超出字符串的范围,则 Python 会抛出错误。Python 样式(与 Perl 不同)是在无法指示要执行的操作时停止,而不仅仅是构造默认值。便利的“切片”语法(如下所示)也可用于从字符串中提取任何子字符串。len(string) 函数返回字符串的长度。[ ] 语法和 len() 函数实际上适用于所有字符串类型(字符串、列表等)。Python 会尝试使其操作在不同类型的操作之间保持一致。Python 新手 bug:不要将“len”用作变量名称,以免屏蔽 len() 函数。“+”运算符可串联两个字符串。请注意,在下面的代码中,变量不是预先声明的,只需将它们赋给变量即可。
s = 'hi'
print(s[1]) ## i
print(len(s)) ## 2
print(s + ' there') ## hi there
与 Java 不同,“+”不会自动将数字或其他类型转换为字符串形式。str() 函数会将值转换为字符串形式,以便将其与其他字符串合并。
pi = 3.14
##text = 'The value of pi is ' + pi ## NO, does not work
text = 'The value of pi is ' + str(pi) ## yes
对于数字,标准运算符 +、/、* 的作用与常规方法相同。没有 ++ 运算符,但 +=、-= 等可正常运行。如果您需要整数除法,请使用 2 个斜杠,例如 6 // 5 为 1
“print”函数通常输出一个或多个 Python 项,后跟换行符。“原始”字符串字面量带有“r”作为前缀,并会传递所有字符而不对反斜杠进行特殊处理,因此 r'x\nx 的计算结果为长度为 4 的字符串“x\nx”。 “print”可以包含多个参数来更改输出内容的方式(请参阅 python.org 输出函数定义),例如将“end”设置为“”,使其在输出完所有项后不再输出换行符。
raw = r'this\t\n and that'
# this\t\n and that
print(raw)
multi = """It was the best of times.
It was the worst of times."""
# It was the best of times.
# It was the worst of times.
print(multi)
字符串方法
以下是一些最常见的字符串方法。方法类似于函数,只不过是在“对象”上运行。如果变量 s 是一个字符串,则代码 s.lower() 会针对该字符串对象运行 lower() 方法并返回结果(关于在对象上运行的方法的思路是构成面向对象的编程 (OPP) 的基本思路之一)。以下是一些最常见的字符串方法:
- s.lower()、s.upper() - 返回字符串的小写或大写版本
- s.strip() - 返回从开头和末尾移除空格的字符串
- s.isalpha()/s.isdigit()/s.isspace()... - 测试所有字符串字符是否位于各种字符类中
- s.startswith('other'))、s.endswith('other') - 用于测试字符串是以给定其他字符串开头还是结尾
- s.find('other') -- 搜索 s 中的指定其他字符串(不是正则表达式),并返回起始位置的第一个索引;如果未找到,则返回 -1
- s.replace('old', 'new') - 返回一个字符串,其中所有出现的“old”均已替换为“new”
- s.split('delim') - 返回由指定分隔符分隔的子字符串列表。分隔符不是正则表达式,只是文本。'aaa,bbb,ccc'.split(',') -> ['aaa', 'bbb', 'ccc']。作为一种特殊的特殊情况,s.split()(不带参数)将针对所有空格字符进行拆分。
- s.join(list) -- 与 merge() 相反,会使用字符串作为分隔符联接指定列表中的元素。例如“---'.join(['aaa', 'bbb', 'ccc']) -> aaa---bbb---ccc
在 Google 中搜索“python str”时,应该会转到官方的 python.org 字符串方法,其中列出了所有 str 方法。
Python 没有单独的字符类型。而 s[8] 等表达式会返回包含该字符的字符串长度 1。使用字符串长度 1 时,运算符 ==, <=, ... 均符合预期,因此大多数人无需知道 Python 没有单独的标量“字符”类型。
字符串切片
“切片”语法可以方便地指代序列的子部分,通常是字符串和列表。切片 s[start:end] 是从开始到结束(但不包括结束)的元素。假设 s =“Hello”
- s[1:4] 为“ell”,即从索引 1 开始,一直延伸到索引 4 时的字符(不包括索引 4)
- s[1:] 为 'ello' - 省略索引默认为字符串的开头或结尾
- s[:] 为“Hello”,省略二者始终都会为整个内容生成副本(这是复制字符串或列表等序列的 Python 方式)
- s[1:100] 为 'ello' - 过大的索引会被截断为字符串长度
从零开始的标准索引号可以轻松地访问字符串开头附近的字符。作为替代,Python 使用负数来轻松访问字符串末尾的字符:s[-1] 是最后一个字符“o”,s[-2] 是“l”是下一个倒数字符,以此类推。负索引编号从字符串的末尾开始计数:
- s[-1] 为 'o' - 最后一个字符(到结尾处的第一个字符)
- s[-4] 为 'e' -- 从第 4 次结束
- s[:-3] 表示“他”,此类字符最多使用最后 3 个字符。
- s[-3:] 为“llo”,从末尾的第 3 个字符开始,一直到字符串的末尾。
对于任何索引 n,它都是简洁的切片。s[:n] + s[n:] == s。这同样适用于 n 负值或出界。或者使用另一种方式 s[:n] 和 s[n:] 将字符串拆分成两个字符串部分,从而保留所有字符。Slice 也支持列表,我们将在后面的列表部分中看到相关信息。
字符串格式
Python 可以完成的一个巧妙操作是自动将对象转换为适合输出的字符串。为此,可采用两种内置方法:格式化字符串字面量(也称为“f 字符串”)和调用 str.format()。
格式化的字符串字面量
您经常会看到在以下情况下使用的格式字符串字面量:
value = 2.791514
print(f'approximate value = {value:.2f}') # approximate value = 2.79
car = {'tires':4, 'doors':2}
print(f'car = {car}') # car = {'tires': 4, 'doors': 2}
格式化的文本字符串带有“f”(例如用于原始字符串的“r”前缀)前缀。 大括号外的任何文本都会直接输出。“{}”中包含的表达式是使用格式规范中所述的格式规范输出的。您可以对格式进行许多巧妙的操作,包括截断和转换为科学记数法以及左/右/中心对齐方式。
f 字符串在您希望输出对象表格,并且希望以不同方式对齐表示不同对象属性的列时非常有用
address_book = [{'name':'N.X.', 'addr':'15 Jones St', 'bonus': 70},
{'name':'J.P.', 'addr':'1005 5th St', 'bonus': 400},
{'name':'A.A.', 'addr':'200001 Bdwy', 'bonus': 5},]
for person in address_book:
print(f'{person["name"]:8} || {person["addr"]:20} || {person["bonus"]:>5}')
# N.X. || 15 Jones St || 70
# J.P. || 1005 5th St || 400
# A.A. || 200001 Bdwy || 5
字符串百分比
Python 也有一个类似于 printf() 的旧版工具,用于整理字符串。% 运算符接受左侧的 printf-type 格式字符串(%d int、%s 字符串、%f/%g 浮点),而右侧元组中的匹配值(元组由以英文逗号分隔的值组成,通常位于括号内):
# % operator
text = "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down." % (3, 'huff', 'puff', 'house')
上一行有点长,假设您想将其拆分为多行。您不能像在其他语言中那样拆分“%”之后的代码行,因为默认情况下 Python 将每行视为一条独立语句(正值是正因如此,所以我们不需要在每行中输入分号)。要解决此问题,请将整个表达式括在外括号中;然后允许表达式跨越多行。这种代码交叉行方法适用于下面所述的各种分组结构:( )、[ ]、{ }。
# Add parentheses to make the long line work:
text = (
"%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down."
% (3, 'huff', 'puff', 'house'))
情况更好,但排队时间有点长。Python 允许您将一行分成多块,然后它会自动串联。为了简化此行,我们可以执行以下操作:
# Split the line into chunks, which are concatenated automatically by Python
text = (
"%d little pigs come out, "
"or I'll %s, and I'll %s, "
"and I'll blow your %s down."
% (3, 'huff', 'puff', 'house'))
字符串(Unicode 与字节)
常规 Python 字符串是 Unicode。
Python 还支持由纯文本字节组成的字符串(以字符串字面量前面的前缀“b”表示),如下所示:
> byte_string = b'A byte string'
> byte_string
b'A byte string'
Unicode 字符串不同于字节字符串,但各类库(例如正则表达式)如果传递任一类型的字符串,均可正常工作。
若要将常规 Python 字符串转换为字节,请对字符串调用 coding() 方法。反过来,字节字符串解码() 方法会将已编码的纯字节转换为 Unicode 字符串:
> ustring = 'A unicode \u018e string \xf1'
> b = ustring.encode('utf-8')
> b
b'A unicode \xc6\x8e string \xc3\xb1' ## bytes of utf-8 encoding. Note the b-prefix.
> t = b.decode('utf-8') ## Convert bytes back to a unicode string
> t == ustring ## It's the same as the original, yay!
True
在文件阅读部分,有一个示例展示了如何打开包含一些编码的文本文件并读出 Unicode 字符串。
if 语句
Python 不使用 { } 封装 if/loops/function 等的代码块。Python 改为使用冒号 (:) 和缩进/空格对语句进行分组。if 的布尔值测试不需要在括号内(与 C++/Java 有明显差异),而且可以包含 *elif* 和 *else* 子句(助记词:“elif”一词与“else”一词的长度相同)。
任何值都可以用作 if-test。“零”值全部计为 false:无、0、空字符串、空列表、空字典。此外,还有两个布尔值类型:True 和 False(转换为整数,这 1 和 0)。Python 具有常规的比较运算:==、!=、<、<=、>、>=。与 Java 和 C 不同,== 已重载,可与字符串正确配合使用。布尔值运算符是拼写*和*、*或*、*不是*(**
if time_hour >= 0 and time_hour <= 24:
print('Suggesting a drink option...')
if mood == 'sleepy' and time_hour < 10:
print('coffee')
elif mood == 'thirsty' or time_hour < 2:
print('lemonade')
else:
print('water')
我发现,在输入上述代码时省略“:”是最常见的语法错误,原因可能是,这与 C++/Java 习惯相比是额外的输入。此外,请不要将布尔值测试放在圆括号中,这是一项 C/Java 习惯。如果代码很短,您可以将代码放在同一行的“:”后面,就像这样(同样,这对于函数、循环等),虽然有些人认为将代码单独放在空间中比较方便。
if time_hour < 10: print('coffee')
else: print('water')