字符串
几乎你写的每个程序都会用到文本。名字、消息、分数、标签……在 Python 中,任何一段文本都叫字符串:只要用引号括起来的值都是字符串。单引号还是双引号,用法完全一样。
greeting = "Hello, world"
username = 'alice'引号的选择唯一要紧的时候,是你的文本里本身就含有引号。这时用另一种引号,就不用去转义了:
note = "It's a great day" # 里面有单引号,用双引号包裹
message = 'She said "hello"' # 里面有双引号,用单引号包裹
escaped = "She said \"hello\"" # 或者用反斜杠转义不可变性
字符串是不可变的:一旦创建,就无法改变。可以把字符串想象成一旦生成就永久固定不变。任何看起来像是在修改字符串的操作,其实都是生成了一个全新的字符串,原来的那个丝毫未变。
name = "alice"
name = name.upper() # "ALICE" 是一个新字符串;"alice" 本身没有变直接的后果是:你不能修改某个特定位置的字符。如果你尝试这样做,Python 会报错。
name = "alice"
name[0] = "A" # TypeError: 'str' object does not support item assignment要得到修改后的字符串,需要用切片或方法构建一个新的。这两种方式下面都会讲到。
name[0] = "A" 这样写是不行的,会引发 TypeError。 索引与切片
字符串中的每个字符都有一个编号位置,从零开始。把这个位置编号放进方括号里,就能读取单个字符。负数则是从末尾往前数。
word = "Python"
# 012345
print(word[0]) # "P"
print(word[2]) # "t"
print(word[5]) # "n"
print(word[-1]) # "n" (最后一个字符)
print(word[-2]) # "o" (倒数第二个)-1 永远是最后一个字符,-2 是倒数第二个,以此类推。当你想拿到字符串末尾的内容而又不想计算它的确切长度时,这很有用。
切片用来取出一段。[start:stop] 包含 start,但不包含 stop:
word = "Python"
print(word[0:2]) # "Py" (位置 0 和 1)
print(word[2:]) # "thon" (从位置 2 到末尾)
print(word[:3]) # "Pyt" (从开头到位置 2)
print(word[:]) # "Python" (整个字符串的一份拷贝)
print(word[::2]) # "Pto" (每隔一个字符取一个)
print(word[::-1]) # "nohtyP" (反转)最常用的三种模式:word[:n] 取前 n 个字符,word[n:] 取从位置 n 开始的所有字符,word[-n:] 取最后 n 个字符。word[::-1] 会反转字符串,第一次看到会觉得有点奇怪,但这是很地道的 Python 写法,你会经常见到它。
word[0] 是第一个字符,word[-1] 是最后一个。切片取的是一段范围:word[start:stop] 包含 start,正好在 stop 之前停下。word[::-1] 能反转字符串,第一次看会觉得挺奇怪,用过之后就会一直用下去。 常用字符串方法
字符串自带一组内置方法:可以直接在任意字符串值上调用的操作。写法是先写字符串(或者装着字符串的变量),再写一个点,然后是方法名。每个方法都会返回一个新字符串,原字符串永远不会被改变。
大小写
text = "Hello, World"
text.lower() # "hello, world"
text.upper() # "HELLO, WORLD"
text.title() # "Hello, World" (每个单词首字母大写)
text.capitalize() # "Hello, world" (只有第一个单词)lower() 和 upper() 是你最常用的两个。lower() 在比较文本时特别有用:"Alice" 和 "alice" 在两边都调用 .lower() 之后就变成一样的了。
空白字符
text = " hello "
text.strip() # "hello" (两端都去掉)
text.lstrip() # "hello " (只去左边)
text.rstrip() # " hello" (只去右边)strip() 会去掉字符串两端的空格。处理用户输入或来自文件的文本时几乎都要用到它,因为多余的空格会造成不易察觉的错误:"alice" != "alice "。
查找
text = "Hello, world"
text.find("world") # 7
text.find("Python") # -1 (没找到)
text.count("l") # 3
text.startswith("Hello") # True
text.endswith("world") # Truefind() 返回某段文本在字符串中开始出现的位置。如果不存在,就返回 -1。当你只想知道字符串是不是以某个特定内容开头或结尾时,用 startswith() 和 endswith()。
替换
text = "Hello, world"
text.replace("world", "Python") # "Hello, Python"
text.replace("l", "L") # "HeLLo, worLd" (所有出现的位置)
text.replace("l", "L", 1) # "HeLlo, world" (只替换第一个)replace() 会把某段文本的所有出现都替换成另一段文本,并返回一个新字符串,原字符串不会变。如果只想替换第一次出现的位置,可以传第三个参数。
拆分与拼接
split() 会按照一个分隔符把字符串切成几段,并以列表形式返回。你要告诉它按什么来切:
csv_row = "小明,28,北京"
parts = csv_row.split(",") # ["小明", "28", "北京"]
" hello world ".split() # ["hello", "world"]split() 返回的是一个列表,即有序的一组值。列表会在专门的 列表 章节详细讲解;现在你只需要把它当作 split() 产生、join() 消费的那一串片段即可。
join() 做的是相反的事:把一个字符串列表合并成一个字符串。放在 .join() 前面的字符串,会被插入到每个项目之间:
words = ["Hello", "world"]
" ".join(words) # "Hello world"
", ".join(words) # "Hello, world"
"".join(words) # "Helloworld"要记住的模式:分隔符.join(字符串列表)。分隔符在左边,列表在右边。" ".join(words) 在每个单词之间放一个空格。"".join(words) 则把它们直接粘在一起,中间什么都不加。
.lower() 和 .upper() 处理大小写,.strip() 去掉多余的空格,.find() 定位文本(找不到时返回 -1),.replace() 替换文本,还有 .split() 配合 sep.join() 拆开字符串再拼回去。 f-string
f-string 可以把值直接嵌入到文本中。在开头的引号前加上 f,然后把任意变量或表达式用花括号括起来。Python 会在代码运行时把值填进去。你还可以在值后面加个冒号来控制它的显示方式。
name = "小明"
score = 94.5
print(f"你好,{name}!") # "你好,小明!"
print(f"分数:{score:.1f}%") # "分数:94.5%"
print(f"2 + 2 = {2 + 2}") # "2 + 2 = 4"
print(f"姓名:{name.upper()}") # "姓名:小明"冒号 : 后面的格式说明符控制值的显示方式:
| 说明符 | 含义 | 示例 |
|---|---|---|
.2f | 保留 2 位小数 | f"{3.14159:.2f}" → "3.14" |
.0% | 百分比,不保留小数 | f"{0.94:.0%}" → "94%" |
, | 千位分隔符 | f"{1000000:,}" → "1,000,000" |
>10 | 在 10 个字符宽度内右对齐 | f"{'hi':>10}" → " hi" |
.2f 是你最常用的:任何时候你展示一个小数,想要一个整洁的数字而不是一长串数字时都会用它。表格里的其他内容会在需要时用到。你可以在 {} 里放任意变量、算术表达式或方法调用。
f,然后把任意变量、求和结果或方法调用放进 {},代码运行时 Python 就会把结果填进去。花括号里的冒号控制显示效果::.2f 保留两位小数,这个你会经常用。比用 + 把文本拼在一起清爽多了。 多行字符串
要写一个跨多行的字符串,用三重引号:开头三个 ",结尾也三个。Python 会把你写的所有换行和空格原样保留。
message = """
亲爱的小明,
感谢您的订购。
祝好,
团队全体成员
"""转义序列
有些字符很难直接在字符串里打出来。Python 用转义序列解决这个问题:一个反斜杠后面跟一个代表某种含义的字母。你会一直用到的两个是 \n(换行)和 \t(制表符)。
| 序列 | 字符 |
|---|---|
\n | 换行 |
\t | 制表符 |
\\ | 字面反斜杠 |
\" | 双引号 |
\' | 单引号 |
print("Line one\nLine two") # 输出两行
print("姓名:\t小明") # 姓名: 小明
path = r"C:\Users\小明\Documents" # 原始字符串,不做转义处理\n 开始新的一行,\t 插入一个制表符,\\ 是一个真正的反斜杠。这两个,\n 和 \t,是你实际会打的。在引号前加个 r,反斜杠就恢复成普通字符了,处理 Windows 路径时很好用。 检查字符串内容
Python 有一些方法能回答关于字符串内容的是/否问题,返回 True 或 False。刚开始最有用的是:isdigit() 能让你在转换之前先检查字符串是不是全是数字,避免因为意外输入而崩溃。
"42".isdigit() # True
"hello".isalpha() # True
"hello42".isalnum() # True
" ".isspace() # True
"Hello".islower() # False
"HELLO".isupper() # Trueis* 方法回答的是是非问题,只有当每个字符都符合条件时才返回 True。你最先会用到的是:在 int() 之前调用 isdigit(),确保这段文本真的是数字,这样奇怪的输入就不会让你崩溃。 实践演练
先去空格,再统一大小写,然后取出你需要的内容。这套流程几乎能处理任何用户输入的文本:
raw_input = " [email protected] "
email = raw_input.strip().lower() # "[email protected]"
at_pos = email.find("@")
username = email[:at_pos]
domain = email[at_pos + 1:]
print(f"用户名:{username}") # "alice"
print(f"域名:{domain}") # "example.com"方法一览表
| 方法 | 作用 |
|---|---|
.lower() / .upper() | 转换为全小写 / 全大写 |
.title() / .capitalize() | 每个单词首字母大写 / 只有第一个单词首字母大写 |
.strip() / .lstrip() / .rstrip() | 去掉两端的空白字符 |
.find(sub) | 第一个匹配项的索引,或 -1 |
.count(sub) | sub 出现的次数 |
.startswith(s) / .endswith(s) | 前缀 / 后缀检查 |
.replace(old, new) | 替换出现的内容 |
.split(sep) | 拆分成一个列表 |
sep.join(iterable) | 把项目拼接成一个字符串 |
.isdigit() / .isalpha() / .isalnum() | 字符类型检查 |

