05.f-string 出来之前,Python 字符串格式化到底有多痛苦
·
f-string 出来之前,Python 字符串格式化到底有多痛苦
如果你是从 Python 3.6 开始学的,你可能不知道以前的人格式化字符串有多折腾。
%s、.format()、位置参数、关键字参数……一套组合拳下来,一个简单的字符串拼接能写三行。
好在 f-string 来了。今天把字符串这事一次讲明白。
创建字符串的三种姿势
s1 = 'hello' # 单引号
s2 = "world" # 双引号,效果一样
s3 = '''第一行
第二行
第三行''' # 三引号,可以跨行
s4 = "It's a nice day" # 字符串里有单引号,用双引号包
s5 = '他说:"你好"' # 字符串里有双引号,用单引号包
单引号和双引号没区别,纯粹看习惯。我一般用双引号,因为英语里缩写多(it's、don't),双引号包裹能省转义。
字符串也能"切片"
字符串本质上是字符的序列,所以支持切片操作:
s = "Hello Python"
print(s[0]) # H — 单个字符
print(s[-1]) # n — 倒数第一个
print(s[0:5]) # Hello — 索引 0 到 5(不含5)
print(s[6:]) # Python — 从索引6到最后
print(s[:5]) # Hello — 从头到索引5
print(s[::2]) # HloPto — 每隔一个字符取一个
print(s[::-1]) # nohtyP olleH — 反转字符串!
切片公式:[start:end:step]
start:默认 0(开头)end:默认末尾(不包含)step:默认 1
反转字符串用 [::-1] 是 Python 的经典 tricks,面试常考。
常用方法:这些是你天天要用的
s = " Hello, Python World! "
# 去空白
print(s.strip()) # "Hello, Python World!"
print(s.lstrip()) # 去左边空白
print(s.rstrip()) # 去右边空白
# 大小写
print(s.upper()) # 全大写
print(s.lower()) # 全小写
print(s.title()) # 每个单词首字母大写
# 查找替换
print(s.find("Python")) # 8 — 返回索引,找不到返回 -1
print(s.index("Python")) # 8 — 找不到直接报错
print(s.replace("Python", "Java")) # 替换
print(s.count("o")) # 2 — 统计出现次数
# 判断
print(s.startswith(" He")) # True
print(s.endswith("!")) # False(末尾有空格)
print("123".isdigit()) # True
print("abc".isalpha()) # True
print("abc123".isalnum()) # True
# 分割与合并
print(s.split()) # ['Hello,', 'Python', 'World!'] — 默认按空白分割
print(s.split(",")) # [' Hello', ' Python World! ']
words = ["Hello", "Python", "World"]
print(" ".join(words)) # "Hello Python World" — 用空格连接
print(", ".join(words)) # "Hello, Python, World"
split() 和 join() 是一对,一个拆一个合,数据清洗时出场率极高。
格式化:f-string 一把梭
以前的方式(了解就行,别用了)
name = "张三"
age = 28
# % 格式化(Python 2 时代的遗产)
print("我叫%s,今年%d岁" % (name, age))
# .format() 方法(Python 3 早期)
print("我叫{},今年{}岁".format(name, age))
print("我叫{0},今年{1}岁,{0}是个好人".format(name, age)) # 可以复用
print("我叫{n},今年{a}岁".format(n=name, a=age)) # 关键字
f-string(Python 3.6+,用这个)
name = "张三"
age = 28
height = 1.75
print(f"我叫{name},今年{age}岁")
print(f"明年我就{age + 1}岁了") # 大括号里可以写表达式
print(f"身高{height:.1f}米") # 保留1位小数
print(f"姓名:{name:>10}") # 右对齐,占10个字符宽度
print(f"进度:{0.865:.1%}") # 百分比格式 → 86.5%
# 多行 f-string
msg = (
f"姓名:{name}\n"
f"年龄:{age}\n"
f"身高:{height}"
)
说实话,f-string 是我最喜欢 Python 3.6 的特性,没有之一。可读性好,性能也比 .format() 快。
编码问题:和乱码说再见
s = "你好"
print(len(s)) # 2 — Python 3 中 len 返回字符数
print(s.encode("utf-8")) # b'\xe4\xbd\xa0\xe5\xa5\xbd' — 6个字节
print(len(s.encode("utf-8"))) # 6
# 编码解码
text = "中文"
encoded = text.encode("utf-8") # 字符串 → 字节
decoded = encoded.decode("utf-8") # 字节 → 字符串
Python 3 默认用 UTF-8,基本告别了 Python 2 时代的编码噩梦。但读写文件时还是要注意指定 encoding="utf-8"。
转义字符:那些反斜杠的事
print("第一行\n第二行") # \n 换行
print("列1\t列2\t列3") # \t 制表符
print("他说:\"你好\"") # \" 转义引号
print("路径:C:\\Users") # \\ 转义反斜杠
# 原始字符串:不转义
print(r"C:\Users\new\text") # 反斜杠保持原样
Windows 路径里的反斜杠和转义符 \n 撞车是常见坑。要么用原始字符串 r"",要么用正斜杠 /,Python 都认。
新手常见坑
坑1:字符串不可变
s = "hello"
# s[0] = "H" # TypeError! 字符串不能原地修改
s = "H" + s[1:] # 只能创建新字符串
坑2:is vs ==
a = "hello"
b = "hello"
print(a == b) # True — 值相等
print(a is b) # True — 同一个对象(短字符串被 Python 缓存了)
# 但别依赖这个行为
c = "hello world!"
d = "hello world!"
print(c is d) # 可能是 False!
判断字符串相等永远用 ==,别用 is。
坑3:split() 的空字符串陷阱
print("".split()) # [] — 空字符串 split 返回空列表
print(" ".split()) # [] — 纯空格也返回空列表
print("a b".split()) # ['a', 'b'] — 正常
动手试试
- 把你的名字反转输出
- 统计一段文字中某个字出现的次数
- 用 f-string 格式化输出一个简单的个人名片
参考答案:
# 1. 名字反转
name = "张三丰"
print(name[::-1]) # 丰三张
# 2. 统计字数
text = "清明时节雨纷纷,路上行人欲断魂"
char = "人"
print(f"'{char}'出现了{text.count(char)}次")
# 3. 名片
name = "张三"
title = "Python 开发工程师"
email = "zhangsan@example.com"
print(f"""
{'='*30}
{name:^20}
{title:^20}
{email:^20}
{'='*30}
""")
写在最后
字符串看着简单,但它是编程里被操作最多的数据类型。日志、配置文件、用户输入、API 返回——全是字符串。
把切片、split/join、f-string 这三板斧练熟,日常 80% 的字符串操作就够了。
下一篇聊聊元组和集合——两个经常被忽略但关键时刻真香的数据结构。
更多推荐
所有评论(0)