3.7. 连接 list 与分割字符串

您有了一个形如 key=value 的 key-value 对 list, 并且想将它们合成为单个字符串。为了将任意包含字符串的 list 连接成单个字符串, 可以使用字符串对象的 join 方法。

下面是一个在 buildConnectionString 函数中连接 list 的例子:

    return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

在我们继续之前有一个有趣的地方。我一直在重复函数是对象, 字符串是对象, 每个东西都是对象的概念。您也许认为我的意思是说字符串 是对象。但是不对, 仔细地看一下这个例子, 您将会看到字符串 ";" 本身就是一个对象, 您在调用它的 join 方法。

总之, join 方法将 list 中的元素连接成单个字符串, 每个元素用一个分号隔开。分隔符不必是一个分号;它甚至不必是单个字符。它可以是任何字符串。

小心
join 只能用于元素是字符串的 list; 它不进行任何的类型强制转换。连接一个存在一个或多个非字符串元素的 list 将引发一个异常。

例 3.27. odbchelper.py 的输出结果

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> ["%s=%s" % (k, v) for k, v in params.items()]
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> ";".join(["%s=%s" % (k, v) for k, v in params.items()])
'server=mpilgrim;uid=sa;database=master;pwd=secret'

上面的字符串是从 odbchelper 函数返回的, 被调用块打印出来, 这样就给出了您开始阅读本章时令人感到吃惊的输出结果。

您可能在想是否存在一个适当的方法来将字符串分割成一个 list。当然有, 它叫做 split

例 3.28. 分割字符串

>>> li = ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> s = ";".join(li)
>>> s
'server=mpilgrim;uid=sa;database=master;pwd=secret'
>>> s.split(";")    1
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> s.split(";", 1) 2
['server=mpilgrim', 'uid=sa;database=master;pwd=secret']
1 splitjoin 正好相反, 它将一个字符串分割成多元素 list。 注意, 分隔符 (“;”) 被完全去掉了, 它没有在返回的 list 中的任意元素中出现。
2 split 接受一个可选的第二个参数, 它是要分割的次数。 (“哦, 可选参数...”, 您将会在下一章中学会如何在您自己的函数中使用它。)
提示
anystring.split(delimiter, 1) 是一个有用的技术, 在您想要搜索一个子串, 然后处理字串前面的东西 (即 list 中第一个元素) 和其后的东西 (即 list 中第二个元素) 时, 使用这个技术。

进一步阅读

3.7.1. 字符串方法的历史注解

当我开始学 Python 时, 我以为 join 是 list 的方法, 它会使用分隔符作为一个参数。很多人都有同样的感觉, 在 join 方法的背后有一段故事。在 Python 1.6 之前, 字符串完全没有这些有用的方法。有一个独立的 string 模块包含所有的字符串函数, 每个函数使用一个字符串作为它的第一个参数。这些函数被认为足够重要, 所以它们移到字符串中去了, 这就使得诸如 lower, uppersplit 之类的函数是有意义的。但许多核心的 Python 程序员反对新的 join 方法, 争论说应该换成是 list 的一个方法, 或不应该移动而仅仅保留为旧的 string 模块 (现仍然还有许多有用的东西在里面) 的一部分。我只使用新的 join 方法, 但是您将会看到代码的其它写法, 并且如果它真的使您感到麻烦, 您可以使用旧的 string.join 函数来替代。