今天,我将向大家分享15个令人相见恨晚的Python字符串格式化技巧,帮你写出更高效、优雅且Pythonic的代码。
1. f'{variabe=}'
如果我们在f-字符串中的变量后添加 = 符号,它会同时打印变量名称和值。
1
|
name: str = 'Jack' age: int = 21 city: str = 'New York' print(f'{name=} {age=} {city=}') # name='Jack' age=21 city='New York'
|
这个技巧对于代码调试和日志记录非常有用。
2. 四舍五入到小数点后N位
要将数值四舍五入到小数点后N位,可以简单使用 {number:.Nf} 的形式(N为具体数字):
1
|
PI: float = 3.141592653589793 print(f'{PI:.2f}') print(f'{PI:.3f}') print(f'{PI:.4f}')
|
3. 四舍五入到 N 个有效数字
要将数值四舍五入到N位有效数字,可以简单使用 {number:.Ng} 的形式(N为具体数字):
1
|
number: int = 131452 print(f'{number:.2g}') # 1.3e+05 print(f'{number:.3g}') # 1.31e+05 print(f'{number:.4g}') # 1.315e+05 x: float = 0.0131452 print(f'{x:.2g}') # 0.013 print(f'{x:.3g}') # 0.0131 print(f'{x:.4g}') # 0.01315
|
4. 格式化原始字符串
原始字符串就是转义字符(\)不再转义其他字符,而只是原本的反斜杠。在字符串前添加 f 就可格式化字符串,在字符串前添加 r 就可让字符串仅表示原始含义。要使字符串既是格式化字符串又是原始字符串,只需在字符串前面添加 fr 或 rf,二者皆可。
1
|
name: str = 'Jack' age: int = 20 print(fr'{name=} \n {age=}') # name='Jack' \n age=20 print(rf'{name=} \n {age=}') # name='Jack' \n age=20
|
5. 使用空格对齐
可以通过 <N, >N 和 ^N 实现字符串的左、右和居中对齐,N 表示填充后的字符串宽度(默认用空格填充):
1
|
fruit: str = 'banana' print(f'[{fruit:<20}]') # [banana ] print(f'[{fruit:>20}]') # [ banana] print(f'[{fruit:^20}]') # [ banana ]
|
注意,如果 fruit 的长度大于20,则会被截断。
6. 使用其他字符对齐
在上面的对齐方式中,默认使用空格填充。实际上,我们可以按自己的意愿指定其他填充字符,比如:
1
|
fruit: str = 'banana' print(f'[{fruit:#<20}]') # [banana##############] print(f'[{fruit:=>20}]') # [==============banana] print(f'[{fruit:*^20}]') # [*******banana*******]
|
7. f-字符串中单双引号的使用
在旧版本的Python(<Python 3.12)中,f-字符串的内外引号形式必须刚好相反,比如,外部为双引号,则内部须为单引号,反之亦然。如果内外引号形式相同则会发生语法错误。
1
|
person_info: dict = {'name': 'Jack', 'age': 25} print(f'Name: {person_info["name"]}; Age: {person_info["age"]}') # Name: Jack; Age: 25 print(f"Name: {person_info['name']}; Age: {person_info['age']}") # Name: Jack; Age: 25 # print(f"Name: {person_info["name"]}; Age: {person_info["age"]}") # SyntaxError: f-string: unmatched '['
|
但是如果Python版本在3.12及以上,则f-字符串的内外引号形式可以相同,比如:
1
|
print(f"Name: {person_info["name"]}; Age: {person_info["age"]}") # Name: Jack; Age: 25 print(f'Name: {person_info['name']}; Age: {person_info['age']}') # Name: Jack; Age: 25
|
8. 大数字格式化—插入千分位符
我们可以在f-字符串中插入千分位符(逗号),增加代码的可读性,语法形式为:{number:,}。
1
|
number: int = 10000000000 print(f'{number:,}') # 10,000,000,000
|
9. 展示原始输出
在f-字符串中的变量后添加 !r 可以让我们展示原始输出,作用相当于 repr(variable):
1
|
name: str = 'Jackzhang' print(f'raw output: {repr(name)}') # raw output: 'Jackzhang' print(f'raw output: {name!r}') # raw output: 'Jackzhang'
|
这个技巧在代码调试和日志记录的场景中会比较有用。
10. 日期时间格式化
在f-字符串中,我们还可以轻松实现日期时间的格式化,格式化代码如下:
-
%Y:表示完整年份,如 2024
-
%y:表示截断的年份,如 24
-
%m:将月份表示为数字
-
%d:将天表示为数字
-
%A:表示星期几(全称),如 Monday, Tuesday, …
-
%a:表示星期几(简称),如 Mon, Tue, …
1
|
from datetime import datetime ddate: datetime = datetime.now() print(f'{ddate: %Y-%m-%d}') # 2024-09-05 print(f'{ddate: %y/%m/%d}') # 24/09/05 print(f'{ddate: %d/%m/%y %A}') # 05/09/24 Thursday print(f'{ddate: %Y-%m-%d %a}') # 05/09/24 Thu
|
其他更多格式化代码可以参考:https://docs.python.org/3/library/datetime.html#format-codes
11. 浮点数转化百分比
我们也可以通过f-字符串直接将数字转换百分比,并且指定百分比中的小数位。
1
|
print(f'{0.25:.0%}') # 25% print(f'{0.5:.1%}') # 50.0% print(f'{0.75:.2%}') # 75.00% print(f'{1.25:.3%}') # 125.000%
|
12. 二、八及十六进制数字展示
在f-字符串中,我们也可以将数字表示为二进制、八进制和十六进制。
-
number:b:以二进制表示数字
-
number:o:以八进制表示数字
-
number:x:以十六进制表示数字
1
|
a, b, c = 4, 16, 128 print(f'binary={a:b} octal={a:o} hexadecimal={a:x}') # binary=100 octal=4 hexadecimal=4 print(f'binary={b:b} octal={b:o} hexadecimal={b:x}') # binary=10000 octal=20 hexadecimal=10 print(f'binary={c:b} octal={c:o} hexadecimal={c:x}') # binary=10000000 octal=200 hexadecimal=80
|
13. 三引号f-字符串
三引号字符串可跨越多行,并且输出与输入完全一致(包括位置、缩进等)。
1
|
person_info: dict = { 'name': 'Jackzhang', 'age': 25, 'gender': 'Male', 'city': 'San Francisco', } msg: str = f''' name: {person_info.get('name')} age: {person_info.get('age')} gender: {person_info.get('gender')} city: {person_info.get('city')} ''' print(msg)
|
14. 带有位置参数的 format()
f-字符串的其中一个局限就是,我们无法将其用作模板字符串,将其存储在数据库中。
为了能够在数据库中存储这样的模板字符串供我们多次调用,可以这样做:
1
|
person_info: dict = { 'name': 'Jackzhang', 'gender': 'Male', } temp_s: str = 'my name is {} and my gender is {}' print(temp_s.format(person_info['name'], person_info['gender'])) # my name is Jackzhang and my gender is Male
|
请注意,第一个参数名称分配给第一个花括号,而第二个参数年龄分配给第二个花括号。如果有更多括号,以此类推。
15. 带有关键字参数的 format()
将 .format() 与位置参数一起使用的限制之一是参数必须严格遵循特定的顺序。为了克服这个限制,我们可以改用关键字参数。关键是我们现在需要将变量名称添加到字符串中,如下所示:
1
|
person_info: dict = { 'name': 'Jackzhang', 'gender': 'Male', } temp_s: str = 'my name is {name} and my gender is {gender}' print(temp_s.format(name=person_info['name'], gender=person_info['gender'])) # my name is Jackzhang and my gender is Male print(temp_s.format(gender=person_info['gender'], name=person_info['name'])) # my name is Jackzhang and my gender is Male
|
从上面的代码片段中我们可以看出,采用关键字参数引用后,即使改变参数顺序,仍然可以获得相同的结果。