Python 字符串插值(制作动态字符串)

2023-10-12

字符串插值是将变量值替换为字符串中占位符的过程。这是 Python 中的一项强大功能,使您能够通过在运行时将变量的值嵌入或替换到字符串中来创建动态字符串。

Python支持多种格式化字符串和执行字符串插值的方式,使得格式字符串更容易维护,也更容易动态修改。

 

 

使用 % 运算符的 Python 字符串插值

The % 操作员允许您使用格式说明符,例如%s对于字符串,%d对于整数,以及%f对于浮点数。


name = "Alice"
age = 25
height = 1.68

print("Hello, my name is %s, I'm %d years old and I'm %.2f meters tall." % (name, age, height))
  

Output:


Hello, my name is Alice, I'm 25 years old and I'm 1.68 meters tall.
  

在本例中,我们使用了%s, %d, and %.2f分别用于字符串、整数和小数点后两位数字的浮点数的格式说明符。
然而,使用该方法有一些限制%操作员:

  1. 随着变量数量或复杂性的增加,它可能更容易出错并且更难以维护。
  2. 存在元组大小与字符串中占位符数量不匹配的风险。

 

str.format()

Python 引入了str.format()Python 3 中的方法,它提供了一种格式化字符串的新方法。

此方法使用占位符,用大括号表示{},您可以在其中放置变量名称。


name = "Bob"
age = 45
print("Hello, my name is {} and I'm {} years old.".format(name, age))
  

Output:


Hello, my name is Bob and I'm 45 years old.
  

在此,论据format函数放在花括号内{}按照它们通过的顺序。这种文字字符串插值方法比使用%操作员。

位置参数

With str.format(),您可以使用位置参数,它允许重新排列显示顺序而不更改传递的参数。


name = "Carol"
age = 50
print("Hello, I'm {1} years old and my name is {0}.".format(name, age))
  

Output:


Hello, I'm 50 years old and my name is Carol.
  

大括号内的数字表示参数的位置。这是一个非常强大的功能,因为它可以重新排列显示顺序而不更改传递的参数。

命名参数

您还可以按名称引用变量替换,并在format method.


print("Hello, I'm {age} years old and my name is {name}.".format(name="David", age=55))
  

Output:


Hello, I'm 55 years old and my name is David.
  

通过在大括号内使用变量名称,可以更轻松地理解哪个变量在何处被替换,特别是当代码中要替换的字符串和数据相距很远时。

它通过名称进行替换并使用命名参数format方法清晰且可维护。

 

格式规范迷你语言

Python 还提供了一种迷你语言来指定替换字段的格式。当您需要控制字段的宽度、数据的对齐方式、小数位数等时,这尤其方便。


import math
print("The value of pi is approximately {0:.3f}.".format(math.pi))
  

Output:


The value of pi is approximately 3.142.
  

Here, {0:.3f}表示我们要将第一个参数格式化为小数点后 3 位的浮点数。

 

模板字符串

The stringPython 中的模块提供了另一种使用 Template 类执行字符串插值的方法。


from string import Template
t = Template('Hello, my name is $name and I am $age years old.')
s = t.substitute(name='Emma', age=35)
print(s)
  

Output:


Hello, my name is Emma and I am 35 years old.
  

在这里,我们首先导入Template类来自string模块。然后,我们使用包含占位符变量的字符串创建一个模板,其前缀为$ symbol.

最后,我们调用substitute模板对象上的方法并传递变量映射来替换占位符。

此方法功能较弱,但对于简单替换或当格式字符串由用户提供时更加用户友好。

 

F 弦

从 Python 3.6 开始,引入了一种新的字符串格式化机制,称为 f-strings(格式化字符串文字)。

这种新的字符串格式化机制使 Python 字符串插值更加可读和简洁。


name = "Frank"
age = 60
print(f"Hello, my name is {name} and I'm {age} years old.")
  

Output:


Hello, my name is Frank and I'm 60 years old.
  

在此代码中,f 字符串是一个文字字符串,以“f”为前缀,其中包含大括号内的表达式。

表达式在运行时计算,并将它们的值插入到字符串中。

嵌入表达式

f 字符串的优点之一是能够在字符串文字中嵌入任意 Python 表达式。


name = "Gary"
age = 65
print(f"{name} will be {age + 5} years old in five years.")
  

Output:


Gary will be 70 years old in five years.
  

在这里,我们在 f 字符串内执行算术运算。表达方式age + 5在运行时评估并将其结果插入到字符串中。

格式说明符

F 字符串支持与str.format() method.


import math
print(f"The value of pi is approximately {math.pi:.3f}.")
  

Output:


The value of pi is approximately 3.142.
  

在此示例中,大括号内的 Python 表达式为math.pi, and :.3f是格式说明符,表示我们要将结果格式化为小数点后 3 位的浮点数。

内联算术和函数调用

您甚至可以使用 f 字符串进行内联算术运算、函数调用等。


x = 10
y = 20
print(f"The sum of {x} and {y} is {x + y}.")
print(f"The square root of {x} is {math.sqrt(x):.2f}.")
  

Output:


The sum of 10 and 20 is 30.
The square root of 10 is 3.16.
  

在这里,我们直接在字符串内执行算术运算和函数调用。这些操作和调用的结果在运行时评估和插入。

Lambda 和 f 弦

您还可以在 f 字符串中使用 lambda 函数。


x = 10
y = 20
print(f"The maximum of {x} and {y} is {(lambda a, b: a if a > b else b)(x, y)}.")
  

Output:


The maximum of 10 and 20 is 20.
  

在此示例中,我们在 f 字符串的大括号内定义了一个 lambda 函数,用于计算两个数字的最大值。我们立即调用这个函数x and y作为参数。

多行 f 字符串

F 字符串也可以跨越多行。当您想要创建在单个字符串中包含多个替换的复杂字符串时,这会很有用。


x = 10
y = 20
z = 30
multi_line_f_string = (
    f"The value of x is {x}."
    f"The value of y is {y}."
    f"The sum of x and y is {x + y}."
    f"The value of z is {z}."
    f"The sum of x, y, and z is {x + y + z}."
)
print(multi_line_f_string)
  

Output:


The value of x is 10.The value of y is 20.The sum of x and y is 30.The value of z is 30.The sum of x, y, and z is 60.
  

在这里,我们通过将整个 f 字符串括在括号内来创建多行 f 字符串。

每一行都是一个单独的 f 字符串,它们全部连接在一起形成一个长字符串。

动态格式化

动态格式化允许您在运行时确定输出字符串的格式。

您可以使用 f 字符串来完成此操作:


for align in ['<', '^', '>']:
    print(f"{'hello':{align}10}")
  

Output:


hello     
  hello   
     hello
  

在此示例中,我们使用带有动态格式说明符的 f 字符串。

在花括号内{}, align是一个变量,它是格式说明符的一部分,其值随着循环的每次迭代而变化。

The 10下列的{align}是格式化字符串的字段宽度。取决于值align,字符串“hello”与字段的左侧、中心或右侧对齐。

 

F 字符串注入攻击以及如何避免它们

如果您不小心在 f 字符串中计算哪些表达式,则可能会发生 F 字符串注入。

如果 f 字符串的任何部分是根据用户输入或外部源构造的,则存在攻击者注入恶意代码的风险。

这可能导致任意代码执行、内存泄漏,甚至崩溃。


import sys
user_input = 'sys.exit()'
dangerous_f_string = f'Hello, {eval(user_input)}!'  

Here, eval(user_input)会导致Python执行sys.exit(),你的程序就会退出。

为了避免这种情况:

切勿从不受信任的输入构造格式字符串:这是防止格式字符串攻击的最直接的方法。始终确保用于构造格式字符串的任何数据都不是来自不受信任的或外部来源。

将模板字符串用于用户提供的格式字符串: The string.TemplatePython中的类提供了一种更安全的方式来实现用户定义的格式字符串。


from string import Template
t = Template('Hello, ${name}!')
user_input = 'sys.exit()'
print(t.safe_substitute(name=user_input))  

 

性能评估(f-string 更快)

我们来进行一个简单的性能评估,来比较Python中四种不同字符串插值方法的速度。

我们将使用timeit模块来测量每种方法所花费的时间。


import timeit
name = "Henry"
age = 70
profession = "doctor"
hobby = "gardening"
location = "New York"

# Using % operator
time_percent_op = timeit.timeit("'Hello, my name is %s. I am %s years old, a %s from %s, and I love %s.' % (name, age, profession, location, hobby)", globals=globals())
print("% Operator: ", time_percent_op)

# Using str.format()
time_str_format = timeit.timeit("'Hello, my name is {}. I am {} years old, a {} from {}, and I love {}.'.format(name, age, profession, location, hobby)", globals=globals())
print("str.format(): ", time_str_format)

# Using Template strings
time_template_str = timeit.timeit("Template('Hello, my name is $name. I am $age years old, a $profession from $location, and I love $hobby.').substitute(name=name, age=age, profession=profession, location=location, hobby=hobby)", setup="from string import Template", globals=globals())
print("Template strings: ", time_template_str)

# Using f-strings
time_f_strings = timeit.timeit("f'Hello, my name is {name}. I am {age} years old, a {profession} from {location}, and I love {hobby}. '", globals=globals())
print("f-strings: ", time_f_strings)
  

Output:


% Operator: 1.0545442999864463
str.format(): 1.1527161999838427
Template strings: 9.305830199999036
f-strings: 0.5057788999984041  

由于其编译时表达式求值,f 字符串往往比其他方法表现得更好。

然而,对于小字符串来说差异并不显着,还应该考虑可读性和安全性等其他因素。

 

将字符串插值与正则表达式结合使用

使用正则表达式时,字符串插值非常有用。让我们用一个例子来证明这一点:


import re
pattern = "fox"
text = "The quick brown fox jumps over the lazy dog"
regex = re.compile(fr"\b{pattern}\b")  # Using f-string
matches = regex.findall(text)
print(matches)
  

Output:


['fox']
  

在此代码中,我们创建一个与单词“fox”匹配的正则表达式。 f 弦fr"\b{pattern}\b"允许我们动态插入变量的值pattern到正则表达式中。

 

Summary

总而言之,这里有一个简单的表格,其中包括 Python 中字符串插值的每种方法的优点和缺点:

Method Strengths Weaknesses
`%` operator Simple and straightforward for basic usage, familiar to C programmers Less readable with multiple substitutions, type specification is mandatory
`str.format()` Improved readability, positional and keyword substitutions, versatile formatting options More verbose compared to f-strings.
Template Strings User-friendly syntax, ideal for simple substitutions or user-supplied format strings, and secured against injection attacks. Limited functionality, no support for complex expressions or custom formatting, slower execution time
f-strings Concise and readable, supports inline expressions and complex formatting, faster execution time Only available in Python 3.6 and above, potential security risk if format string is constructed at runtime

请记住,最合适的方法通常取决于您的具体用例。根据上下文,无论是格式的复杂性、性能考虑还是您正在使用的 Python 版本,这些方法中的每一种都可能更适合。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 字符串插值(制作动态字符串) 的相关文章

  • 如何在Python的SciPy中更改稀疏矩阵中的元素?

    我构建了一个小代码 我想用它来解决涉及大型稀疏矩阵的特征值问题 它工作正常 我现在要做的就是将稀疏矩阵中的一些元素设置为零 即最顶行中的元素 对应于实现边界条件 我可以调整下面的列向量 C0 C1 和 C2 来实现这一点 不过我想知道是否有
  • scipy 将一个稀疏矩阵的所有行附加到另一个稀疏矩阵

    我有一个 numpy 矩阵 想在其中附加另一个矩阵 这两个矩阵的形状为 m1 shape 2777 5902 m2 shape 695 5902 我想将 m2 附加到 m1 以便新矩阵的形状为 m new shape 3472 5902 当
  • 如何在 Windows 64 上安装 NumPy?

    NumPy 安装程序在注册表中找不到 python 路径 无法安装 需要 Python 2 5 版本 但在注册表中未找到该版本 OK 我必须修改注册表吗 我已经修改了 PATH 以指向Python25安装目录 我可以检查一下您使用的是什么安
  • Sublime Text 插件开发中的全局 Python 包

    一 总结 我不知道 Sublime Text 插件开发人员如何使用 Sublime Text 查找全局 Python 包 而不是 Sublime Text 目录的 Python 包 Sublime Text使用自己的Python环境 而不是
  • 用缺失的日期填充其他列 Nan Pandas DataFrame

    我实际上是从几个 Excel 文件中提取数据来监控我的每日卡路里摄入量 我设法使用列表理解来生成日期 我尝试使用合并或连接 但它不起作用 ValueError 您正在尝试合并对象和 float64 列 date list 2021 05 2
  • pyspark 数据框中的自定义排序

    是否有推荐的方法在 pyspark 中实现分类数据的自定义排序 我理想地寻找 pandas 分类数据类型提供的功能 因此 给定一个数据集Speed列 可能的选项是 Super Fast Fast Medium Slow 我想实现适合上下文的
  • 工作日重新订购 Pandas 系列

    使用 Pandas 我提取了一个 CSV 文件 然后创建了一系列数据来找出一周中哪几天崩溃最多 crashes by day bc DAY OF WEEK value counts 然后我将其绘制出来 但当然它按照与该系列相同的排名顺序绘制
  • Python3.0 - 标记化和取消标记化

    我正在使用类似于以下简化脚本的内容来解析较大文件中的 python 片段 import io import tokenize src foo bar src bytes src encode src io BytesIO src src l
  • Pandas:如果单元格包含特定文本则删除行

    pandas 中的这段代码不起作用 如果该列包含提供的任何文本 数字 我希望它删除该行 目前 我只能在单元格与我的代码中传递的确切文本匹配时才能使其工作 因为它只删除显示 Fin 的单元格不是金融或金融 df2 df df Team Fin
  • Gspread如何复制sheet

    在 Stackoverflow 上进行谷歌搜索和搜索后 我想我找不到有关如何复制现有工作表 现有模板工作表 并将其保存到另一个工作表中的指南 根据文档 有重复表 https gspread readthedocs io en latest
  • Jython 和 SAX 解析器:允许的实体不超过 64000 个?

    我做了一个简单的测试xml saxJython 中的解析器在处理大型 XML 文件 800 MB 时遇到以下错误 Traceback most recent call last File src project xmltools py li
  • 使用“默认”环境变量启动新的子进程

    我正在编写一个构建脚本来解析依赖的共享库 及其共享库等 这些共享库在正常情况下是不存在的PATH环境变量 为了使构建过程正常工作 让编译器找到这些库 PATH已更改为包含这些库的目录 构建过程是这样的 加载器脚本 更改 PATH gt 基于
  • Python SSL X509:KEY_VALUES_MISMATCH

    Python HTTPS server from http server import HTTPServer SimpleHTTPRequestHandler import ssl https stackoverflow com a 408
  • 如何与其他用户一起使用 pyenv?

    如何与其他用户一起使用 pyenv 例如 如果我在用户 test 的环境中安装了 pyenv 则当我以 test 身份登录时可以使用 pyenv 但是 当我以其他用户 例如 root 身份登录时如何使用 pyenv 即使你这么做了 我也会s
  • Django 与谷歌图表

    我试图让谷歌图表显示在我的页面上 但我不知道如何将值从 django 视图传递到 javascript 以便我可以绘制图表 姜戈代码 array Year Sales Expenses 2004 1000 400 2005 1170 460
  • 双击打开 ipython 笔记本

    相关文章 通过双击 osx 打开 ipython 笔记本 https stackoverflow com questions 16158893 open an ipython notebook via double click on osx
  • TKinter 中的禁用/启用按钮

    我正在尝试制作一个像开关一样的按钮 所以如果我单击禁用按钮 它将禁用 按钮 有效 如果我再次按下它 它将再次启用它 我尝试了 if else 之类的东西 但没有成功 这是一个例子 from tkinter import fenster Tk
  • 从 pandas DataFrame 中删除少于 K 个连续 NaN

    我正在处理时间序列数据 我在从数据帧列中删除小于或等于阈值的连续 NaN 时遇到问题 我尝试查看一些链接 例如 标识连续 NaN 出现的位置以及计数 Pandas NaN 孔的游程长度 https stackoverflow com que
  • 多个对象以某种方式相互干扰[原始版本]

    我有一个神经网络 NN 当应用于单个数据集时 它可以完美地工作 但是 如果我想在一组数据上运行神经网络 然后创建一个新的神经网络实例以在不同的数据集 甚至再次同一组数据 上运行 那么新实例将产生完全错误的预测 例如 对 XOR 模式进行训练
  • 使用ssl和socket的python客户端身份验证

    我有一个 python 服务器 需要客户端使用证书进行身份验证 我如何制作一个客户端脚本 使用客户端证书由 python 中的服务器使用 ssl 和套接字模块进行身份验证 有没有仅使用套接字和 ssl 而不扭曲的示例 from OpenSS

随机推荐

  • Python 中的 K 均值聚类:实用指南

    目录 What Is Clustering 聚类技术概述 分区聚类 层次聚类 基于密度的聚类 How to Perform K Means Clustering in Python 了解 K 均值算法 使用 Python 编写您的第一个 K
  • 在 Python 中使用 lru_cache 进行缓存

    有很多方法可以实现快速响应的应用程序 缓存是一种方法 如果使用得当 可以使事情变得更快 同时减少计算资源的负载 蟒蛇的功能工具模块附带 lru cache 装饰器 这使您能够使用以下命令缓存函数的结果最近最少使用 LRU 策略 这是一种简单
  • 拼写错误、缺失或误用 Python 关键字

    以下是有关 Python 关键字的更多信息的资源 Python 关键字 简介 真正的 Python 文章 Python 3 8 关键字 Python 文档
  • Python 标准 REPL:快速尝试代码和想法

    目录 Getting to Know the Python Standard REPL 什么是 Python 的交互式 Shell 或 REPL 为什么使用 Python REPL Starting and Ending REPL Inte
  • 使用 Fabric 和 Ansible 自动化 Django 部署

    目录 设置和配置 Fabric Setup 设置 SSH 密钥 强化用户密码 安装 Ansible 依赖项 将 SELinux 设置为宽容模式 升级服务器 完整性检查 Ansible Primer 剧本 示例手册 Playbook Setu
  • 第 27 集:准备面试 Python 练习题

    第 27 集 准备面试 Python 练习题 真正的 Python 播客 2020 年 9 月 18 日47m RSS Apple Podcasts Google Podcasts Spotify More 播客瘾君子 灰蒙蒙 袖珍铸件 投
  • Python 基础知识:函数和循环(摘要)

    在本视频课程中 您了解了两个最基本的概念 在编程中 函数和循环 首先 您学习了如何定义自己的自定义函数 你看到了 该函数由两部分组成 这函数签名 这开始于def关键字并包括函数名称和函数参数 这函数体 其中包含每当调用该函数时运行的代码 函
  • Python 的 urllib.request 用于 HTTP 请求

    目录 使用 urllib request 的基本 HTTP GET 请求 The Nuts and Bolts of HTTP Messages 了解什么是 HTTP 消息 了解 urllib request 如何表示 HTTP 消息 关闭
  • Django Ninja 的隐蔽 REST API(摘要)

    在本课程中 您已经了解了 Django Ninja REST API 库的所有内容 使用 Ninja 您可以 使用装饰器快速包装 Django 视图创建 REST API 端点 使用类型注释定义变量和参数 写Schema和ModelSche
  • Python 中的 Dijkstra 算法(查找最短路径)

    Dijkstra算法的工作原理是通过迭代找到节点的最短距离值 直到达到实际的最短距离 Dijkstra 算法的一个关键方面是它使用优先队列从尚未处理的节点集中选择具有最小暂定距离的顶点 当前节点被标记为已访问 并检查其所有邻居节点是否有更优
  • 使用 Pandas read_excel 读取 Excel 文件

    Pandas read excel是一个函数蟒蛇熊猫库允许我们在 Python 中读取 Excel 文件并将其转换为数据框 object read excel函数可以导入具有不同扩展名的Excel文件 例如 xls xlsx xlsm和 o
  • Pandas where() 方法:带条件过滤

    The where中的方法Pandas允许您根据条件过滤 DataFrame 或 Series 类似于 SQL 的 WHERE 子句 您是否曾经发现自己需要根据特定条件替换 DataFrame 中的某些值 或者可能想要屏蔽不符合某些条件的数
  • Linux find 命令:综合指南

    The findLinux 中的命令是一个功能强大的实用程序 用于根据您指定的条件搜索和定位文件和目录 它可以按名称 大小 类型 权限 日期和许多其他标准快速定位文件 目录 hide 1 基本语法 2 Finding Files by Na
  • 了解 Linux Sed 命令中的保持缓冲区

    保持缓冲区在sed允许您临时存储和检索输入行 将其视为辅助存储器 您可以在使用主模式空间时放置数据 当您需要一次执行涉及多行的操作时 保持缓冲区特别有用 保留缓冲区不是立即处理和打印每一行 而是让您保存一行 处理其他行 然后在需要时返回保存
  • Python zip 函数教程(简单示例)

    The zip function 是一个内置的 Python 函数 它接受两个或多个序列或集合 如列表或字符串 并创建一个并行聚合每个集合中的元素的迭代器 这种组合这些值的过程称为 压缩 它源于将两个单独的项目集合压缩在一起的想法 目录 h
  • Linux 测试命令:Bash 中的比较

    The testLinux 中的命令是一个命令行实用程序 用于检查和评估条件 它经常被用在bash 脚本测试文件属性 比较字符串和数字 并支持 AND OR 和 NOT 运算的复杂逻辑评估 目录 hide 1 语法和返回值 2 File T
  • Python 中的无穷大万无一失的指南

    数字是编程不可或缺的一部分 因此 编程语言支持各种数据类型来表示不同类型的数字 并提供各种使用它们的方法 这些数据类型中的每一种都对其可以表示的数字范围有一定的限制 有些可以代表小范围的数字 而另一些则支持很大的数字范围 根据我们的用例 我
  • Linux 中的 Grep 命令(附示例)

    在本教程中 您将学习如何使用非常重要的grepLinux 中的命令 我们将讨论为什么掌握这个命令很重要 以及如何在命令行的日常任务中使用它 让我们通过一些解释和示例来深入探讨 目录 hide 1 为什么我们使用 grep 2 查找字符串 3
  • 如何一步步安装Linux

    如何安装Linux 当您选择了最佳 Linux 发行版 现在是时候了解如何安装 Linux 了 如果你想安装Linux 有两种方法可以实现 第一种方式就是下载您想要的 Linux 发行版并将其刻录到 DVD 或 USB 记忆棒中 然后用它启
  • Python 字符串插值(制作动态字符串)

    字符串插值是将变量值替换为字符串中占位符的过程 这是 Python 中的一项强大功能 使您能够通过在运行时将变量的值嵌入或替换到字符串中来创建动态字符串 Python支持多种格式化字符串和执行字符串插值的方式 使得格式字符串更容易维护 也更