将字符列表转换为字符串

486
如果我有一个字符列表:
a = ['a','b','c','d']

如何将它转换为单个字符串?

a = 'abcd'

9个回答

691

使用空字符串的 join 方法将所有字符串用空字符串连接起来,如下所示:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'

1
如何在字符之间添加空格?有没有不需要遍历整个字符串的方法? - clifgray
18
请使用 ' '.join(list) 将列表中的元素用空格拼接起来。其中引号内的空格表示要在每个元素之间插入一个空格。 - clifgray
1
一个很好的事情是,如果你想将列表写入带有每个项目换行的txt文件中,你可以使用'\n'.join(a)。 - Norfeldt
37
澄清一下:"".join(['a','b','c']) 的意思是将数组中的所有元素连接起来,用空字符串作为分隔符。同样地," hi ".join(["jim", "bob", "joe"]) 会创建一个字符串 "jim hi bob hi joe" - Jacklynn
@DanielStutzbach 这太聪明了。谢谢!仍然可以在Python3x - 2021中使用! - William Martens

48

这在许多流行的编程语言中有效,例如JavaScript和Ruby,为什么Python不行?

>>> ['a', 'b', 'c'].join('')
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'

很奇怪,在Python中join方法是在str类上定义的:

# this is the Python way
"".join(['a','b','c','d'])
为什么在Python的list对象中,像JavaScript或其他流行脚本语言一样,join不是一个方法?这是Python社区思维方式的一个例子。由于join返回一个字符串,应该将其放置在字符串类中,而不是列表类中,因此str.join(list)方法的含义是:使用str作为分隔符(在这种情况下,str是一个空字符串)将列表连接成一个新字符串。
在一段时间后,我开始喜欢这种思考方式。我可以抱怨Python设计的许多问题,但不能抱怨其内部的一致性。

8
join方法成为字符串方法而非列表方法的主要原因在于它接受任何可迭代对象,而不仅限于列表。你可以使用生成器表达式、字典、集合、各种视图等等。因此,它比大多数语言中的数组连接操作更加灵活。 - rosuav
我正在比较Python的string.join()和许多动态语言中大多数集合都有的join()方法。关于可迭代对象,我想对于这些语言来说并不是问题,因为将可迭代对象封装在集合构造器中并在join()方法中链接起来同样容易(且易读)。 - Paulo Scardine
是的,假设它们具有惰性列表(Haskell风格),或者您习惯于在开始之前将列表合并到内存中。我的观点是Python的做法并不是武断的,它有非常好的理由。 - rosuav
1
这不是任意的决定,而是一项设计决策,旨在避免在每个类中污染命名空间。 :-) - Paulo Scardine
没错。而且,这些并不全是类 - “iterable”是一种协议,而不是一个类。你可以使用任何可迭代对象进行过滤、映射、连接等操作。 - rosuav

19
如果你的Python解释器比较旧(例如1.5.2版本,在一些较老的Linux发行版上很常见),你可能没有在旧字符串对象上作为方法使用join(),而需要使用字符串模块。例如:
a = ['a', 'b', 'c', 'd']

try:
    b = ''.join(a)

except AttributeError:
    import string
    b = string.join(a, '')

字符串b将为'abcd'


10

这可能是最快的方法:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'

4
@WinstonEwert 是的,昨天我在写一个程序,需要做这样一件事情,并对我的程序中计算行数的几种方式进行了基准测试,结果显示它比 '' .join(['a','b','c']) 快大约20%。 - bigeagle
2
我自己的基准测试显示连接速度快了7倍。http://pastebin.com/8nSc5Ek1。你介意分享你的基准测试吗? - Winston Ewert
21
过早优化。这句话很难读懂并理解正在发生什么。除非用户需要操作性能,否则一个简单的''.join()更易于阅读。 - Luiz Damim
5
程序员需要记住最快的方法来处理事情,一个稍微慢一点的简单操作并不是什么大问题。然而,几乎所有编写的程序最终都会变得臃肿且占用太多资源。如果我们不养成尽可能精简代码的习惯,就会得到一个像……嗯,像Windows Vista或Linux中的Upstart这样的世界,它们是许多小捷径导致“臃肿和浮动”的好例子,也很丑陋。为什么不使用str().join(a)呢?在我看来,这是100%表达力的。 - osirisgothra
1
...但是我仍然会在愚蠢的小实验中使用简单的那个,而在需要速度的重量级任务中使用另一个。我只是想说,我们应该养成适当宽容这些事情的习惯。 - osirisgothra
显示剩余4条评论

4
该 reduce 函数同样适用。
import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'

1
总是让我感到困扰的是,运算符并没有成为一等公民。例如,在Scheme中,可以这样写:(reduce + h)。 - Brian Minton
在Scheme中,(reduce + '' h)(apply + h)都可以工作。但是在Python中,加法运算符只接受两个操作数,因此需要使用reduce。否则,您可以执行operator.add(*h),因为在Python中,apply已被正式弃用,而推荐使用扩展调用语法(又称http://en.wikipedia.org/wiki/Variadic_function)。 - Brian Minton

4
如果列表中包含数字,则可以使用map()join()一起使用。
例子:
>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459

使用''.join([str(i) for i in arr])更符合Pythonic的风格。 - user1767754
2
@user1767754 好吧,Guido 更喜欢那种风格,但使用 map 函数也完全没有问题。 - itsbruce

3
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'

7
这会相当慢。使用''.join(h)方法可以远远超过逐个添加的方法。 - Martijn Pieters
2
在“Python圣经”(那本1400多页的书)中,有很多地方告诉我们这样做是错误的,应尽可能避免。这也是一个明显的标志,表明使用者是一个不了解Python的初学者(并不是贬低其功能...好吧),虽然它可能有效,但你会听到大约5000人告诉你不要这样做。 - osirisgothra
这被称为Shlemiel画家算法,尽管公平地说,在本页上使用reduce的许多更高级的答案都归结于相同的事情。 - ggorlen

2
除了最常用的 str.join 方法之外,另一种可能性是使用 io.StringIO 并滥用 writelines 一次性写入所有元素:
import io

a = ['a','b','c','d']

out = io.StringIO()
out.writelines(a)
print(out.getvalue())

打印:

abcd

使用这种方法时,如果使用生成器函数或不是tuplelist的可迭代对象,则可以避免join创建临时列表来一次性分配正确大小(由于内存方面,一个由1个字符字符串组成的列表非常昂贵)。
如果您的内存不足,并且输入是惰性评估对象,则此方法是最佳解决方案。

0
您还可以这样使用{{link1:operator.concat()}}:
>>> from operator import concat
>>> a = ['a', 'b', 'c', 'd']
>>> reduce(concat, a)
'abcd'

如果您正在使用Python 3,则需要添加前缀:
>>> from functools import reduce

由于Python 3中已经移除了内置的reduce()函数,现在它被放在了functools.reduce()中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接