2010-01-25 48 views
28

鉴于这种无伤大雅的小名单:大多数Python的方式来连接字符串

>>> lst = ['o','s','s','a','m','a'] 

我的目标是pythonically串联使用下列方法之一小鬼:

A.纯醇”字符串函数把工作做好,总之,没有进口

>>> ''.join(lst) 
'ossama' 

B.拉姆达,λ,拉姆达

>>> reduce(lambda x, y: x + y, lst) 
'ossama' 

C.全球化(什么都不做,进口的一切)

>>> import functools, operator 
>>> functools.reduce(operator.add, lst) 
'ossama' 

请建议其他Python化的方式来实现这一坦荡任务。

请排名(pythonic水平)和率解决方案给出简明的解释。

在这种情况下,最好的pythonic解决方案是最好的编码解决方案吗?

回答

29

查看关于python优化的Guido的essay,它涵盖了将数字列表转换为字符串。除非你有一个好的理由,否则使用join的例子。

55
''.join(lst) 

唯一的Python的方式:

  • 明确的(即什么都大男孩做的,他们希望看到什么),
  • 简单(无需额外的进口需要,稳定在所有版本) ,
  • 快(用C写)和
  • 简洁(在一个空字符串中加入iterable元素!)。
+2

虽然基于减少的解决方案是优雅的,我的功能程序员赞赏他们,我必须同意join()确实是唯一的pythonic解决方案。 – liwp 2010-01-25 16:10:13

+1

SilentGhost是正确的。字符串有一个接受迭代的连接方法,所以使用其他任何东西都不是pythonic。 – stefanw 2010-01-25 16:10:14

+0

所以 - 人们,请检查“bytearray”本机类型,我的答案如下)。尽管如此,Join是无与伦比的Python 2.5。 – jsbueno 2010-01-25 16:51:12

5

这里是最Python的方式:

out = "" 
for x in range(len(lst)): 
    for y in range(len(lst)): 
    if x + y == len(lst)-1: 
     out = lst[y] + out 
+3

我敢打赌,有办法降低pythonicity。 ;) – 2010-01-25 16:31:37

+0

不是他要求的,但我看到你的观点..... :-) – 2010-01-25 17:22:13

5

我自己使用“加盟”的方式,但是从Python 2.6中有是很少使用的基本类型:字节组

Bytearrays可以是非常有用的 - 对于包含文本的字符串,因为最好的事情是在unicode中,“连接”方式是要走的路 - 但如果你正在处理二进制数据,而不是字节数组既可以是更Python,更高效:

>>> lst = ['o','s','s','a','m','a'] 
>>> a = bytearray(lst) 
>>> a 
bytearray(b'ossama') 
>>> print a 
ossama 

它是一个内置的数据类型:无需要进口 - 只用那么 - 你可以使用列表中的ByteArray isntead下手 - 因此他们应该比“连接”效率更高,因为没有数据复制来获取字节数组的字符串表示。

从SilenGhost但
+0

嗯..检查:“bytearray”构造函数可以得到一个unicode字符串和一个“编码”参数,因此它可以处理与unicode以及。例如。 :a = bytearray(u“déja-vu”,encoding =“utf8”) – jsbueno 2010-01-25 16:46:51

+1

,只是bytearrays既不是pythonic也不是有效的。它们旨在用于完全不同的目的,它们在py2.6中的行为与py3k中的行为不同。 – SilentGhost 2010-01-25 21:21:08

+0

@SilentGhost:感谢您的反馈 - 我可以在哪里阅读更多信息?即使它们的效率不如它们可能首先看到的那么高,我怀疑“连接”可能会更快,这仅仅是因为每个部分创建了一个新的连贯对象。 (我打算今天晚些时候做一些基准测试) – jsbueno 2010-01-26 11:00:58

3

伟大的答案,只是对提出reduce“另类”

除非你有一个非常非常非常使用的理由或+operator.add连接字符串(最常见的一个几句话,你没有固定数量的字符串),你应该始终使用join

只是因为每个+生成一个新的字符串,它是两个字符串的连接,除非只生成一个最终字符串的连接。因此,假设您已经有了3串:

A + B + C 
--> 
D = A + B 
final = D + C 

好吧,似乎并不并不多,但你一定要保留内存为D.此外,由于蟒蛇使用字符串,生成一个新的,中间,字符串,它在某种程度上昂贵...

现在,5串

A + B + C + D + E 
--> 
F = A + B 
G = F + C 
H = G + D 
final = H + E 

假设最好的情况(如果我们这样做(A + B)+(C + d)+ E,我们将在内存中同时有三个中间字符串),这就产生了3个中间字符串......你必须生成一个新的python对象,reser ve内存空间,释放内存几次...另外调用Python函数的开销(这不是很小)

现在想想它与200个字符串。我们最终会得到大量的中间字符串,每个字符串都耗费了很多时间,成为python上的完整列表,并且调用了很多operator.add函数,每个函数都有其开销......即使您使用reduce功能,它不会帮助。这是一个需要用不同方法管理的问题:join,它只产生ONE完整的python字符串,最后一个,并调用一个python函数。

(当然,join,或其他类似的,专门用于阵列功能)

16

当然它是join。我怎么知道?让我们以一种非常愚蠢的方式来做:
如果问题只是添加2个字符串,那么最有可能使用str1 + str2。需要什么才能将其提升到新的水平?本能地,对于大多数(我认为),将使用sum。让我们来看看这是怎么回事:

In [1]: example = ['a', 'b', 'c'] 
In [2]: sum(example, '') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython console> in <module>() 
TypeError: sum() can't sum strings [use ''.join(seq) instead] 

哇! Python简单地告诉我要使用什么! :)