Python拼接字符串的7种方式详解


Posted in Python onMarch 19, 2020

忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串。相信不少同学会有同感。

几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型。而拼接字符串是必备的一种技能。今天,我跟大家一起来学习Python拼接字符串的七种方式。

1、来自C语言的%方式

print('%s %s' % ('Hello', 'world'))
>>> Hello world

%号格式化字符串的方式继承自古老的C语言,这在很多编程语言都有类似的实现。上例的%s是一个占位符,它仅代表一段字符串,并不是拼接的实际内容。实际的拼接内容在一个单独的%号后面,放在一个元组里。

类似的占位符还有:%d(代表一个整数)、%f(代表一个浮点数)、%x(代表一个16进制数),等等。%占位符既是这种拼接方式的特点,同时也是其限制,因为每种占位符都有特定意义,实际使用起来太麻烦了。

2、format()拼接方式

# 简洁版
s1 = 'Hello {}! My name is {}.'.format('World', 'Python猫')
print(s1)
>>>Hello World! My name is Python猫.

# 对号入座版
s2 = 'Hello {0}! My name is {1}.'.format('World', 'Python猫')
s3 = 'Hello {name1}! My name is {name2}.'.format(name1='World', name2='Python猫')
print(s2)
>>>Hello World! My name is Python猫.
print(s3)
>>>Hello World! My name is Python猫.

这种方式使用花括号{}做占位符,在format方法中再转入实际的拼接值。容易看出,它实际上是对%号拼接方式的改进。这种方式在Python2.6中开始引入。

上例中,简洁版的花括号中无内容,缺点是容易弄错次序。对号入座版主要有两种,一种传入序列号,一种则使用key-value的方式。实战中,我们更推荐后一种,既不会数错次序,又更直观可读。

3、() 类似元组方式

s_tuple = ('Hello', ' ', 'world')
s_like_tuple = ('Hello' ' ' 'world')

print(s_tuple) 
>>>('Hello', ' ', 'world')
print(s_like_tuple) 
>>>Hello world

type(s_like_tuple) >>>str

注意,上例中s_like_tuple并不是一个元组,因为元素间没有逗号分隔符,这些元素间可以用空格间隔,也可以不要空格。使用type()查看,发现它就是一个str类型。我没查到这是啥原因,猜测或许()括号中的内容是被Python优化处理了。

这种方式看起来很快捷,但是,括号()内要求元素是真实字符串,不能混用变量,所以不够灵活。

# 多元素时,不支持有变量
str_1 = 'Hello'
str_2 = (str_1 'world')
>>> SyntaxError: invalid syntax
str_3 = (str_1 str_1)
>>> SyntaxError: invalid syntax
# 但是下面写法不会报错
str_4 = (str_1)

4、面向对象模板拼接

from string import Template
s = Template('${s1} ${s2}!') 
print(s.safe_substitute(s1='Hello',s2='world')) 
>>> Hello world!

说实话,我不喜欢这种实现方式。浓浓的一股被面向对象思想毒害的臭味。

就不多说了。

5、常用的+号方式

str_1 = 'Hello world! ' 
str_2 = 'My name is Python猫.'
print(str_1 + str_2)
>>>Hello world! My name is Python猫.
print(str_1)
>>>Hello world!

这种方式最常用、直观、易懂,是入门级的实现方式。但是,它也存在两处让人容易犯错的地方。

首先,新入门编程的同学容易犯错,他们不知道字符串是不可变类型,新的字符串会独占一块新的内存,而原来的字符串保持不变。上例中,拼接前有两段字符串,拼接后实际有三段字符串。

其次,一些有经验的老程序员也容易犯错,他们以为当拼接次数不超过3时,使用+号连接符就会比其它方式快(ps:不少Python教程都是如此建议),但这没有任何合理根据。

事实上,在拼接短的字面值时,由于CPython中的 常数折叠 (constant folding)功能,这些字面值会被转换成更短的形式,例如'a'+'b'+'c' 被转换成'abc','hello'+'world'也会被转换成'hello world'。这种转换是在编译期完成的,而到了运行期时就不会再发生任何拼接操作,因此会加快整体计算的速度。

常数折叠优化有一个限度,它要求拼接结果的长度不超过20。所以,当拼接的最终字符串长度不超过20时,+号操作符的方式,会比后面提到的join等方式快得多,这与+号的使用次数无关。

题外话:你是否觉得20这个数字很熟悉呢?没错,字符串类的特权种族也是以20为限。当时也有一个例子,展示了编译期和运行期的区别,建议你去回看。

6、join()拼接方式

str_list = ['Hello', 'world']
str_join1 = ' '.join(str_list)
str_join2 = '-'.join(str_list)
print(str_join1) >>>Hello world
print(str_join2) >>>Hello-world

str对象自带的join()方法,接受一个序列参数,可以实现拼接。拼接时,元素若不是字符串,需要先转换一下。可以看出,这种方法比较适用于连接序列对象中(例如列表)的元素,并设置统一的间隔符。

当拼接长度超过20时,这种方式基本上是首选。不过,它的缺点就是,不适合进行零散片段的、不处于序列集合的元素拼接。

7、f-string方式

name = 'world'
myname = 'python_cat'
words = f'Hello {name}. My name is {myname}.'
print(words)
>>> Hello world. My name is python_cat.

f-string方式出自PEP 498(Literal String Interpolation,字面字符串插值),从Python3.6版本引入。其特点是在字符串前加 f 标识,字符串中间则用花括号{}包裹其它字符串变量。

这种方式在可读性上秒杀format()方式,处理长字符串的拼接时,速度与join()方法相当。

尽管如此,这种方式与其它某些编程语言相比,还是欠优雅,因为它引入了一个 f 标识。而其它某些程序语言可以更简练,比如shell:

name="world"
myname="python_cat"
words="Hello ${name}. My name is ${myname}."
echo $words
>>>Hello world. My name is python_cat.

总结一下,我们前面说的“字符串拼接”,其实是从结果上理解。若从实现原理上划分的话,我们可以将这些方法划分出三种类型:

格式化类:%、format()、template

拼接类:+、()、join()

插值类:f-string

当要处理字符串列表等序列结构时,采用join()方式;拼接长度不超过20时,选用+号操作符方式;长度超过20的情况,高版本选用f-string,低版本时看情况使用format()或join()方式。

Python字符串拼接:方法、效率、场景

一般对于Python字符串拼接来讲,方法有以下三种:

方法一:通过 “ + ” 号拼接

 因python中的字符串是不可变的类型,所以使用 " + " 号链接会生成一个新字符串,同时也重新申请了一段内存。

 所以当拼接次数太多,使用 " + " 号拼接效率是非常低的。

contact = '命运' + '先知'
print(contact)

结果:命运先知 

方法二 :格式化方式拼接

 format()方法是pyhton最未推荐的字符串格式化的方法。
 python2.6之前,格式化字符串都是用 % 的方式,原理与format()相同。
 format 函数可以接受不限个参数,位置可以通过 {} 中的下标索引任意设置。
 format 函数中的{} 中还有很多功能,比如{:.of}表示不带小数,{:0>2d}表示向数字左边填补0,宽度为2。

contact =  '{1}{0}'.format('命运','先知')
print(contact)

结果:先知命运

contact =  '%s%s' % ('命运','先知')
print(contact)

结果:命运先知

方法三 :join方式拼接 效率最高

使用略微复杂,但对于多个字符串进行拼接时,效率很高,只会有一次内存的申请。所以很擅长对列表的处理。

liststr = ['命运' , '先知']
contact =  ''.join(liststr)
print(contact)

结果:命运先知

更多关于Python字符串操作方法请查看下面的相关链接

Python 相关文章推荐
Python中转换角度为弧度的radians()方法
May 18 Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
Nov 05 Python
Python实现字符串匹配算法代码示例
Dec 05 Python
python实现感知器算法(批处理)
Jan 18 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
May 09 Python
pytorch使用指定GPU训练的实例
Aug 19 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
Anaconda和ipython环境适配的实现
Apr 22 Python
Python requests模块安装及使用教程图解
Jun 30 Python
django 获取字段最大值,最新的记录操作
Aug 09 Python
python开发入门——set的使用
Sep 03 Python
python在package下继续嵌套一个package
Apr 14 Python
python图形界面开发之wxPython树控件使用方法详解
Feb 24 #Python
pytorch使用tensorboardX进行loss可视化实例
Feb 24 #Python
python绘制动态曲线教程
Feb 24 #Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
Feb 23 #Python
Windows系统下pycharm中的pip换源
Feb 23 #Python
推荐8款常用的Python GUI图形界面开发框架
Feb 23 #Python
PyQt5高级界面控件之QTableWidget的具体使用方法
Feb 23 #Python
You might like
暴雪前总裁遗憾:没尽早追赶Dota 取消星际争霸幽灵
2020/03/08 星际争霸
关于拼配咖啡,你要知道
2021/03/03 咖啡文化
PHP数组函数array_multisort()用法实例分析
2016/04/02 PHP
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
2009/11/30 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
js格式化货币数据实现代码
2013/09/04 Javascript
新增加的内容是如何将div的scrollbar自动移动最下面
2014/01/02 Javascript
SeaJS入门教程系列之完整示例(三)
2014/03/03 Javascript
node.js中的fs.mkdir方法使用说明
2014/12/17 Javascript
js字符串操作方法实例分析
2015/05/06 Javascript
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
2015/08/21 NodeJs
JS构造函数与原型prototype的区别介绍
2016/07/04 Javascript
javascript十六进制数字和ASCII字符之间的转换方法
2016/12/27 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
2017/12/19 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
2018/03/07 Javascript
Vue实现移动端左右滑动效果的方法
2018/11/27 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
微信小程序点击顶部导航栏切换样式代码实例
2019/11/12 Javascript
python实现向ppt文件里插入新幻灯片页面的方法
2015/04/28 Python
利用python画一颗心的方法示例
2017/01/31 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
在python 中实现运行多条shell命令
2019/01/07 Python
使用Python正则表达式操作文本数据的方法
2019/05/14 Python
Python基本数据结构之字典类型dict用法分析
2019/06/08 Python
Python 程序报错崩溃后如何倒回到崩溃的位置(推荐)
2020/06/23 Python
一款简洁的纯css3代码实现的动画导航
2014/10/31 HTML / CSS
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
几道Web/Ajax的面试题
2016/11/05 面试题
鲜花方阵解说词
2014/02/13 职场文书
2014年办公室工作总结范文
2014/11/12 职场文书
2016年幼儿园庆六一开幕词
2016/03/04 职场文书
2019最新版试用期劳动合同模板!
2019/07/04 职场文书
乔迁新居祝福语
2019/11/04 职场文书
《进击的巨人》新联动CM 兵长强势出击兽巨人
2022/04/05 日漫
python多次执行绘制条形图
2022/04/20 Python