Python拼接字符串的7种方法总结


Posted in Python onNovember 01, 2018

前言

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

在Python中,我们经常会遇到字符串的拼接问题,几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型。而拼接字符串是必备的一种技能。今天,我跟大家一起来学习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这个数字很熟悉呢?没错,我们之前在《Python中的“特权种族”是什么?》中提到过,字符串类的特权种族也是以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()方式。

One more thing:

你以为这就要结束了?

图样!这不是我的风格!

我的风格是发散思考、系统思考、以及追求编程哲学的思考。

最近,我在读《黑客与画家》,保罗•格雷厄姆在书中提出了这个问题:

从语义上看,字符串或多或少可以理解成列表的一个子集,其中的每一个元素都是字符。那么,为什么还需要把字符串单列为一种数据结构呢?

作者认为“编程语言设置字符串似乎就是一个过早优化的例子”,这个观点令我大为震撼!前文提到的七种拼接字符串的方法瞬间变成纸,薄得似乎一触就破。

但是,作者认为这还不够,他还有更惊人想法:

还有比这更惊人的预言。在逻辑上其实不需要对整数设置单独的表示法,因为可以把它们也看作列表,整数n可以用一个n元素的列表表示。… 编程语言会发展到放弃基本数据类型之一的整数这一步吗?

不知道你读完这段话,有何感想。我在阅读时,虽然有上下文语境的铺垫,还是惊叹不已。

在此,先行预告一下:下期荐书系列的书目是《黑客与画家》,到时候,还会有幸运抽奖,送出一本《黑客与画家》,敬请留意。

附几个相关PEP链接:

  • https://www.python.org/dev/peps/pep-0215/
  • https://www.python.org/dev/peps/pep-0292/
  • https://www.python.org/dev/peps/pep-3101/
  • https://www.python.org/dev/peps/pep-0498/

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python的加密模块md5、sha、crypt使用实例
Sep 28 Python
Python lxml模块安装教程
Jun 02 Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
Jan 20 Python
对Python中for复合语句的使用示例讲解
Nov 01 Python
python直接获取API传递回来的参数方法
Dec 17 Python
基于django channel实现websocket的聊天室的方法示例
Apr 11 Python
Python绘图Matplotlib之坐标轴及刻度总结
Jun 28 Python
Python3.7 读取 mp3 音频文件生成波形图效果
Nov 05 Python
Python计算机视觉里的IOU计算实例
Jan 17 Python
浅谈python中频繁的print到底能浪费多长时间
Feb 21 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
Apr 22 Python
python可迭代对象去重实例
May 15 Python
在python中bool函数的取值方法
Nov 01 #Python
numpy给array增加维度np.newaxis的实例
Nov 01 #Python
Python 中导入csv数据的三种方法
Nov 01 #Python
numpy向空的二维数组中添加元素的方法
Nov 01 #Python
CentOS 7 安装python3.7.1的方法及注意事项
Nov 01 #Python
在Python中增加和插入元素的示例
Nov 01 #Python
Python对象中__del__方法起作用的条件详解
Nov 01 #Python
You might like
BBS(php & mysql)完整版(五)
2006/10/09 PHP
zend optimizer在wamp的基础上安装图文教程
2013/10/26 PHP
PHP之将POST数据转化为字符串的实现代码
2016/11/03 PHP
Laravel中前端js上传图片到七牛云的示例代码
2017/09/04 PHP
php实现根据身份证获取精准年龄
2020/02/26 PHP
通过PHP实现用户注册后邮箱验证激活
2020/11/10 PHP
基于JQuery的动态删除Table表格的行和列的代码
2011/05/12 Javascript
jquery给图片添加鼠标经过时的边框效果
2013/11/12 Javascript
Js为表单动态添加节点内容的方法
2015/02/10 Javascript
JavaScript中指定函数名称的相关方法
2015/06/04 Javascript
使用jquery实现仿百度自动补全特效
2015/07/23 Javascript
jquery自定义表单验证插件
2016/10/12 Javascript
AngularJS开发教程之控制器之间的通信方法分析
2016/12/25 Javascript
JavaScrpt中如何使用 cookie 设置查看与删除功能
2017/07/09 Javascript
vuex直接赋值的三种方法总结
2018/09/16 Javascript
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
简单学习5种处理Vue.js异常的方法
2019/06/17 Javascript
Vue 实现CLI 3.0 + momentjs + lodash打包时优化
2019/11/13 Javascript
原生js实现的观察者和订阅者模式简单示例
2020/04/18 Javascript
[54:41]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VGJ.T VS paiN
2018/03/31 DOTA
[01:01:22]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python之wxPython菜单使用详解
2014/09/28 Python
python difflib模块示例讲解
2017/09/13 Python
使用Python来开发微信功能
2018/06/13 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
2019/08/01 Python
Python字符串的修改方法实例
2019/12/19 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
python 代码运行时间获取方式详解
2020/09/18 Python
Css3新特性应用之视觉效果实例
2016/12/12 HTML / CSS
OPPO手机官方商城:中国手机市场出货量第一品牌
2017/10/18 全球购物
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
湖南省党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
行政介绍信范文
2015/05/04 职场文书
2015年加油站工作总结
2015/05/13 职场文书
信用卡催款律师函
2015/05/27 职场文书
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js