15 KiB
在 Python 中拆分、连接和连接字符串
原文:https://realpython.com/python-string-split-concatenate-join/
*立即观看**本教程有真实 Python 团队创建的相关视频课程。和书面教程一起看,加深理解:Python 中的拆分、串联、连接字符串
生活中很少有保证:死亡、税收、程序员需要处理字符串。字符串可以有多种形式。它们可以是非结构化的文本、用户名、产品描述、数据库列名,或者任何我们用语言描述的东西。
由于字符串数据几乎无处不在,当涉及到字符串时,掌握交易工具很重要。幸运的是,Python 使得字符串操作变得非常简单,尤其是与其他语言甚至更老版本的 Python 相比。
在本文中,你将学习一些最基本的字符串操作:拆分、连接和连接。你不仅将学会如何使用这些工具,还将对它们的工作原理有更深的理解。
***参加测验:***通过我们的交互式“Python 中字符串的拆分、连接和联接”测验来测试您的知识。完成后,您将收到一个分数,以便您可以跟踪一段时间内的学习进度:
*参加测验
免费奖励: 并学习 Python 3 的基础知识,如使用数据类型、字典、列表和 Python 函数。
拆分字符串
在 Python 中,字符串被表示为 str 对象,这些对象是不可变的:这意味着内存中表示的对象不能被直接改变。这两个事实可以帮助你学习(然后记住)如何使用.split()。
您猜到字符串的这两个特性与 Python 中的拆分功能有什么关系了吗?如果您猜测.split()是一个 实例方法 ,因为字符串是一种特殊的类型,那么您就猜对了!在其他一些语言中(比如 Perl),原始字符串作为独立的.split()函数的输入,而不是字符串本身调用的方法。
注意:调用字符串方法的方式
像.split()这样的字符串方法在这里主要显示为在字符串上调用的实例方法。它们也可以被称为静态方法,但这并不理想,因为它更“罗嗦”为了完整起见,这里有一个例子:
# Avoid this:
str.split('a,b,c', ',')
与首选用途相比,这种方法体积庞大且不实用:
# Do this instead:
'a,b,c'.split(',')
关于 Python 中实例、类和静态方法的更多信息,请查看我们的深度教程。
字符串不变性呢?这应该提醒你,字符串方法不是就地操作,而是它们在内存中返回一个新的对象。
注:就地操作
就地操作是直接改变调用它们的对象的操作。一个常见的例子是在列表上使用的 .append()方法:当你在一个列表上调用.append()时,该列表通过将.append()的输入添加到同一个列表中而被直接改变。
无参数分割
在深入探讨之前,我们先看一个简单的例子:
>>> 'this is my string'.split()
['this', 'is', 'my', 'string']
这实际上是一个.split()调用的特例,我选择它是因为它简单。如果没有指定任何分隔符,.split()会将任何空格作为分隔符。
对.split()的裸调用的另一个特性是,它会自动删除开头和结尾的空白,以及连续的空白。比较调用以下不带分隔符参数的字符串上的.split()和使用' '作为分隔符参数的情况:
>>> s = ' this is my string '
>>> s.split()
['this', 'is', 'my', 'string']
>>> s.split(' ')
['', 'this', '', '', 'is', '', 'my', 'string', '']
首先要注意的是,这展示了 Python 中字符串的不变性:对.split()的后续调用处理原始字符串,而不是第一次调用.split()的列表结果。
您应该看到的第二件事——也是最主要的一件事——是简单的.split()调用提取了句子中的单词,并丢弃了任何空白。
指定分隔符
另一方面,.split(' '),就更加字面了。当有前导或尾随分隔符时,您将得到一个空字符串,您可以在结果列表的第一个和最后一个元素中看到它。
如果有多个连续的分隔符(例如“this”和“is”之间以及“is”和“my”之间),第一个分隔符将被用作分隔符,随后的分隔符将作为空字符串进入结果列表。
注:.split() 调用中的分隔符
虽然上面的例子使用单个空格字符作为输入到.split()的分隔符,但是您并不局限于用作分隔符的字符类型或字符串长度。唯一的要求是您的分隔符是一个字符串。你可以使用从"..."到"separator"的任何东西。
用最大分割限制分割
.split()还有一个可选参数叫做maxsplit。默认情况下,.split()会在被调用时进行所有可能的拆分。然而,当您给maxsplit赋值时,将只进行给定数量的分割。使用我们之前的示例字符串,我们可以看到maxsplit在运行:
>>> s = "this is my string"
>>> s.split(maxsplit=1)
['this', 'is my string']
正如您在上面看到的,如果您将maxsplit设置为1,第一个空白区域被用作分隔符,其余的被忽略。让我们做些练习来检验一下到目前为止我们所学的一切。
给一个负数作为maxsplit参数会怎么样?
.split()将在所有可用的分隔符上分割字符串,这也是当maxsplit未设置时的默认行为。
您最近收到了一个格式非常糟糕的逗号分隔值(CSV)文件。您的工作是将每一行提取到一个列表中,列表中的每个元素代表该文件的列。是什么让它格式不好?“地址”字段包含多个逗号,但需要在列表中表示为单个元素!
假设您的文件已经作为以下多行字符串加载到内存中:
Name,Phone,Address
Mike Smith,15554218841,123 Nice St, Roy, NM, USA
Anita Hernandez,15557789941,425 Sunny St, New York, NY, USA
Guido van Rossum,315558730,Science Park 123, 1098 XG Amsterdam, NL
您的输出应该是一个列表列表:
[
['Mike Smith', '15554218841', '123 Nice St, Roy, NM, USA'],
['Anita Hernandez', '15557789941', '425 Sunny St, New York, NY, USA'],
['Guido van Rossum', '315558730', 'Science Park 123, 1098 XG Amsterdam, NL']
]
每个内部列表代表我们感兴趣的 CSV 的行,而外部列表将它们放在一起。
这是我的解决方案。有几种方法可以解决这个问题。重要的是,您使用了带有所有可选参数的.split(),并获得了预期的输出:
input_string = """Name,Phone,Address
Mike Smith,15554218841,123 Nice St, Roy, NM, USA
Anita Hernandez,15557789941,425 Sunny St, New York, NY, USA
Guido van Rossum,315558730,Science Park 123, 1098 XG Amsterdam, NL"""
def string_split_ex(unsplit):
results = []
# Bonus points for using splitlines() here instead,
# which will be more readable
for line in unsplit.split('\n')[1:]:
results.append(line.split(',', maxsplit=2))
return results
print(string_split_ex(input_string))
我们在这里调用.split()两次。第一种用法可能看起来有点吓人,但是不要担心!我们会一步一步来,你会习惯这些表达方式。让我们再来看看第一个.split()呼叫:unsplit.split('\n')[1:]。
第一个元素是unsplit,它只是指向你的输入字符串的变量。然后我们有我们的.split()呼叫:.split('\n')。在这里,我们拆分一个叫做换行符的特殊字符。
\n是做什么的?顾名思义,它告诉正在读取字符串的任何东西,它后面的每个字符都应该显示在下一行。在像我们的input_string这样的多行字符串中,每行的末尾都有一个隐藏的\n。
最后一部分可能是新的:[1:]。到目前为止,这条语句在内存中给了我们一个新的列表,并且[1:]看起来像一个列表索引符号,它确实是——有点像!这个扩展的索引符号给了我们一个列表片。在这种情况下,我们获取索引1处的元素及其之后的所有内容,丢弃索引0处的元素。
总之,我们遍历一个字符串列表,其中每个元素表示多行输入字符串中除第一行之外的每一行。
在每个字符串中,我们使用,作为拆分字符再次调用.split(),但是这一次我们使用maxsplit只拆分前两个逗号,保持地址不变。然后,我们将该调用的结果附加到名副其实的results数组中,并将其返回给调用者。
串联和连接字符串
另一个基本的字符串操作与拆分字符串相反:字符串连接。如果你没见过这个词,不用担心。这只是“粘在一起”的一种花哨说法
用+运算符连接
有几种方法可以做到这一点,这取决于你想要达到的目标。最简单也是最常见的方法是使用加号(+)将多个字符串加在一起。只需在想要连接的任意多的字符串之间放置一个+:
>>> 'a' + 'b' + 'c'
'abc'
为了与数学主题保持一致,您也可以将字符串相乘来重复它:
>>> 'do' * 2
'dodo'
记住,字符串是不可变的!如果您连接或重复存储在变量中的字符串,您必须将新字符串赋给另一个变量才能保留它。
>>> orig_string = 'Hello'
>>> orig_string + ', world'
'Hello, world'
>>> orig_string
'Hello'
>>> full_sentence = orig_string + ', world'
>>> full_sentence
'Hello, world'
如果我们没有不可变的字符串,full_sentence将会输出'Hello, world, world'。
另一点需要注意的是,Python 不做隐式字符串转换。如果你试图将一个字符串和一个非字符串类型连接起来,Python 会抛出一个TypeError :
>>> 'Hello' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must be str, not int
这是因为您只能将字符串与其他字符串连接起来,如果您来自像 JavaScript 这样试图进行隐式类型转换的语言,这可能是一种新的行为。
用.join() 在 Python 中从列表到字符串
还有另一种更强大的方法将字符串连接在一起。在 Python 中,你可以用join()方法从一个列表变成一个字符串。
这里的常见用例是,当您有一个由字符串组成的 iterable(如列表)时,您希望将这些字符串组合成一个字符串。和.split()、.join()一样,是一个字符串实例方法。如果你所有的字符串都在一个 iterable 中,你在哪个上面调用.join()?
这是一个有点棘手的问题。请记住,当您使用.split()时,您是在想要拆分的字符串或字符上调用它。相反的操作是.join(),所以您可以在想要用来将字符串的 iterable 连接在一起的字符串或字符上调用它:
>>> strings = ['do', 're', 'mi']
>>> ','.join(strings)
'do,re,mi'
在这里,我们用逗号(,)连接strings列表的每个元素,并在其上调用.join()而不是strings列表。
如何使输出文本更具可读性?
你可以做的一件事是增加间距:
>>> strings = ['do', 're', 'mi']
>>> ', '.join(strings)
'do, re, mi'
通过在连接字符串中添加一个空格,我们极大地提高了输出的可读性。这是您在连接字符串以提高可读性时应该始终牢记的事情。
.join()的聪明之处在于,它将你的“joiner”插入到你想要连接的 iterable 的字符串之间,而不是仅仅在 iterable 的每个字符串的末尾添加 joiner。这意味着如果你传递一个大小为1的 iterable,你将看不到你的 joiner:
>>> 'b'.join(['a'])
'a'
使用我们的网页抓取教程,你已经建立了一个伟大的天气抓取工具。但是,它在列表的列表中加载字符串信息,每个列表都包含您要写入 CSV 文件的唯一一行信息:
[
['Boston', 'MA', '76F', '65% Precip', '0.15 in'],
['San Francisco', 'CA', '62F', '20% Precip', '0.00 in'],
['Washington', 'DC', '82F', '80% Precip', '0.19 in'],
['Miami', 'FL', '79F', '50% Precip', '0.70 in']
]
您的输出应该是如下所示的单个字符串:
"""
Boston,MA,76F,65% Precip,0.15in
San Francisco,CA,62F,20% Precip,0.00 in
Washington,DC,82F,80% Precip,0.19 in
Miami,FL,79F,50% Precip,0.70 in
"""
对于这个解决方案,我使用了 list comprehension,这是 Python 的一个强大特性,允许您快速构建列表。如果你想学习更多关于它们的知识,可以看看这篇伟大的文章,它涵盖了 Python 中所有可用的理解。
下面是我的解决方案,从一个列表列表开始,以一个字符串结束:
input_list = [
['Boston', 'MA', '76F', '65% Precip', '0.15 in'],
['San Francisco', 'CA', '62F', '20% Precip', '0.00 in'],
['Washington', 'DC', '82F', '80% Precip', '0.19 in'],
['Miami', 'FL', '79F', '50% Precip', '0.70 in']
]
# We start with joining each inner list into a single string
joined = [','.join(row) for row in input_list]
# Now we transform the list of strings into a single string
output = '\n'.join(joined)
print(output)
这里我们使用.join()不是一次,而是两次。首先,我们在列表理解中使用它,它将每个内部列表中的所有字符串组合成一个字符串。接下来,我们用我们之前看到的换行符\n连接这些字符串。最后,我们简单地打印结果,这样我们就可以验证它是否如我们所期望的那样。
将所有这些联系在一起
虽然对 Python 中最基本的字符串操作(拆分、连接和连接)的概述到此结束,但仍有大量的字符串方法可以让您更轻松地操作字符串。
一旦你掌握了这些基本的字符串操作,你可能想学习更多。幸运的是,我们有许多很棒的教程来帮助您完全掌握 Python 支持智能字符串操作的特性:
***参加测验:***通过我们的交互式“Python 中字符串的拆分、连接和联接”测验来测试您的知识。完成后,您将收到一个分数,以便您可以跟踪一段时间内的学习进度:
*参加测验
立即观看**本教程有真实 Python 团队创建的相关视频课程。和书面教程一起看,加深理解:Python 中的拆分、串联、连接字符串******