翻译自Do Not Use “+” to Join Strings in Python
文章目录
- 避免使用“+”操作符在python中连接字符串
- 开始
- 连接多个字符串
- `join()`方法背后的逻辑
- 总结
避免使用“+”操作符在python中连接字符串
当我开始使用python时,由于非常直观因此常常使用+
来连接字符串——正如许多其他程序设计语言如java的连接方式。
但是,很快我发现许多开发者似乎更喜欢使用.join()
而非+
.本文将介绍两者之间的区别以及为什么你需要避免使用+
.
开始
作为初学者,或者从其他语言转向python的开发者,很容易将代码写为下面的形式:
str1 = "I love "
str2 = "python."
print(str1 + str2)
# I love python
当你使用python越来越多时,你可能意识到有些人更喜欢使用join()
方法:
str1 = "I love "
str2 = "python."
print(''.join([str1, str2])
# I love python
老实说,当我第一次看见上面这种写法是,我想的是为什么需要这种不直观且看上去很抽象的方式。
连接多个字符串
然而,有一次我需要将一个列表中的多个字符串连接起来。
strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']
一开始,我写下了如下代码:
strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']
def join_strs(strs):
result = ''
for s in strs:
result +=' ' + s
return result[1:]
join_strs(strs)
# 'Life is short, I use Python'
在这个例子中,我必须使用一个for循环来一个接一个地连接字符串。同时,循环中的字符串必须前面统一加上一个空格以保证最终结果的每个字符串前面都有一个空格——当然第一个字符串是例外。当然你可以通过判定索引来保证index=0时空格不会被加到字符串前。但无论如何你都需要一个for循环来做这些事。
在写下这段代码后,我会想起我曾经看到过.join()
方法,也许是时候使用它了:
strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']
def join_strs_better(strs):
return ' '.join(strs)
join_strs_better(strs)
# 'Life is short, I use Python'
这是多么容易!只需要一行代码所有问题都被解决了。由于.join()
方法被一个字符串对象调用——这个字符串对象使用列表中的所有字符串来生成一个新的字符串——因此你无需担心开头会被添加一个多余的空格。
你不会真的以为这是我们避免使用+
的唯一理由吧?下一节将介绍更多两者的区别!
join()
方法背后的逻辑
我们相对两种方法的性能做出对比,通过在Jupyter Notebook中使用%timeit
来评估:
这段代码是在译者的笔记本跑的,cpui7-7700hq,如果在您自己的电脑上跑cpu的性能将决定时间长短)
基于100k次实验的结果是值得相信的。很明显,join()
方法比使用+
快了4倍有余。
为什么会这样?
下面是使用+
时的概念图
Using + operator and for-loop to join strings in a list
这展示了for循环和+
操作符的步骤:
- 每次循环发现列表中的下一个字符串
- python执行器执行语句
result += ' ' + s
,分配表示' '
的内存 - python执行器发现空格需要和字符串连接起来,因此它将为发现的字符串申请内存地址,第一次循环的字符串为“Life”
- 每次循环,执行器都需要分配两次内存地址,一次分配给空格一次分配给当前循环的字符串
- 总共12次内存分配
那join()
方法被调用时会发生什么?
- 执行器计算列表中由多少个字符串(6个)
- 通过上一步执行器知道需要执行字符串连接共6-1=5次
- 上两步的结果使执行器知道总共需要分配11块内存空间,因此将一次性地提前调用11块内存空间
- 将字符串按顺序连接,返回结果
很显然两种方法的主要区别就在于内存调用次数导致的性能提升。
想象一下对六个字符串的连接,join()
方法已经比+
快四倍还多。那如果我们需要连接很大数量的字符串呢?显然两者会有更大的差异。
总结
在这篇短文中,我将python中+
和join()
两种连接字符串的方法进行了对比。显然后者的表现优于前者许多。
学习一种编程语言通常是是一个很长的曲线,但是Python使得初学者更加容易接受——这无疑是很棒的。但是当我们入门并开始使用Python后,我们不应该停留在之前所使用Python的方式。实际上,大师和普通开发者的区别往往来自于对细节的了解。
让我们继续发现更多Python编程的细节来使自己更加精通Python!
单词
- comparison 比较
- intuitive /ɪn’tuɪtɪv/直观
- conceptual graph概念图
- allocations /ˌælə’keʃən/调用
- %timeit jupyter notebook计时