Bra*_*Deo 115 python string python-2.7 python-3.x
将两个字符串拼接在一起的最pythonic方法是什么?
例如:
输入:
u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
l = 'abcdefghijklmnopqrstuvwxyz'
Run Code Online (Sandbox Code Playgroud)
输出:
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
Run Code Online (Sandbox Code Playgroud)
Jim*_*ard 127
对我来说,最pythonic*方式是以下几乎相同的东西,但使用+
运算符连接每个字符串中的单个字符:
res = "".join(i + j for i, j in zip(u, l))
print(res)
# 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
Run Code Online (Sandbox Code Playgroud)
它也比使用两个join()
调用更快:
In [5]: l1 = 'A' * 1000000; l2 = 'a' * 1000000
In [6]: %timeit "".join("".join(item) for item in zip(l1, l2))
1 loops, best of 3: 442 ms per loop
In [7]: %timeit "".join(i + j for i, j in zip(l1, l2))
1 loops, best of 3: 360 ms per loop
Run Code Online (Sandbox Code Playgroud)
存在更快的方法,但它们经常使代码混淆.
注意:如果两个输入字符串是不相同的长度,则较长的一个将被截断,zip
停在较短字符串的结尾迭代.在这种情况下,zip
不应该从模块中使用zip_longest
(izip_longest
在Python 2中)itertools
以确保两个字符串都完全耗尽.
*引用Python的Zen:可读性计数.
Pythonic = 对我来说可读性 ; i + j
只是在视觉上解析,至少对我的眼睛而言.
Mik*_*ler 62
其他方式:
res = [''] * len(u) * 2
res[::2] = u
res[1::2] = l
print(''.join(res))
Run Code Online (Sandbox Code Playgroud)
输出:
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
Run Code Online (Sandbox Code Playgroud)
看起来更快:
%%timeit
res = [''] * len(u) * 2
res[::2] = u
res[1::2] = l
''.join(res)
100000 loops, best of 3: 4.75 µs per loop
Run Code Online (Sandbox Code Playgroud)
比目前为止最快的解决方案:
%timeit "".join(list(chain.from_iterable(zip(u, l))))
100000 loops, best of 3: 6.52 µs per loop
Run Code Online (Sandbox Code Playgroud)
也适用于较大的字符串:
l1 = 'A' * 1000000; l2 = 'a' * 1000000
%timeit "".join(list(chain.from_iterable(zip(l1, l2))))
1 loops, best of 3: 151 ms per loop
%%timeit
res = [''] * len(l1) * 2
res[::2] = l1
res[1::2] = l2
''.join(res)
10 loops, best of 3: 92 ms per loop
Run Code Online (Sandbox Code Playgroud)
Python 3.5.1.
u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
l = 'abcdefghijkl'
Run Code Online (Sandbox Code Playgroud)
zip()
等效)min_len = min(len(u), len(l))
res = [''] * min_len * 2
res[::2] = u[:min_len]
res[1::2] = l[:min_len]
print(''.join(res))
Run Code Online (Sandbox Code Playgroud)
输出:
AaBbCcDdEeFfGgHhIiJjKkLl
Run Code Online (Sandbox Code Playgroud)
itertools.zip_longest(fillvalue='')
相当于)min_len = min(len(u), len(l))
res = [''] * min_len * 2
res[::2] = u[:min_len]
res[1::2] = l[:min_len]
res += u[min_len:] + l[min_len:]
print(''.join(res))
Run Code Online (Sandbox Code Playgroud)
输出:
AaBbCcDdEeFfGgHhIiJjKkLlMNOPQRSTUVWXYZ
Run Code Online (Sandbox Code Playgroud)
Tig*_*kT3 49
随着join()
和zip()
.
>>> ''.join(''.join(item) for item in zip(u,l))
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
Run Code Online (Sandbox Code Playgroud)
Vee*_*rac 18
在Python 2上,到目前为止,更快的做事方式是,对于小字符串列表切片的速度约为3倍,对于长字符串切换速度约为30倍,
res = bytearray(len(u) * 2)
res[::2] = u
res[1::2] = l
str(res)
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于Python 3.你可以实现类似的东西
res = bytearray(len(u) * 2)
res[::2] = u.encode("ascii")
res[1::2] = l.encode("ascii")
res.decode("ascii")
Run Code Online (Sandbox Code Playgroud)
但到那时你已经失去了对小字符串列表切片的收益(它仍然是长字符串速度的20倍),这甚至不适用于非ASCII字符.
FWIW,如果你是在大量的串这样做的,需要每个周期,以及由于某种原因必须使用Python字符串...以下是如何做到这一点:
res = bytearray(len(u) * 4 * 2)
u_utf32 = u.encode("utf_32_be")
res[0::8] = u_utf32[0::4]
res[1::8] = u_utf32[1::4]
res[2::8] = u_utf32[2::4]
res[3::8] = u_utf32[3::4]
l_utf32 = l.encode("utf_32_be")
res[4::8] = l_utf32[0::4]
res[5::8] = l_utf32[1::4]
res[6::8] = l_utf32[2::4]
res[7::8] = l_utf32[3::4]
res.decode("utf_32_be")
Run Code Online (Sandbox Code Playgroud)
特殊套管较小型的常见情况也会有所帮助.FWIW,这只是长字符串列表切片速度的3倍,而小字符串则慢 4到5倍.
无论哪种方式,我更喜欢这些join
解决方案,但由于其他地方提到时间,我想我也可以加入.
Pad*_*ham 16
如果你想要最快的方式,你可以将itertools与operator.add
:
In [36]: from operator import add
In [37]: from itertools import starmap, izip
In [38]: timeit "".join([i + j for i, j in uzip(l1, l2)])
1 loops, best of 3: 142 ms per loop
In [39]: timeit "".join(starmap(add, izip(l1,l2)))
1 loops, best of 3: 117 ms per loop
In [40]: timeit "".join(["".join(item) for item in zip(l1, l2)])
1 loops, best of 3: 196 ms per loop
In [41]: "".join(starmap(add, izip(l1,l2))) == "".join([i + j for i, j in izip(l1, l2)]) == "".join(["".join(item) for item in izip(l1, l2)])
Out[42]: True
Run Code Online (Sandbox Code Playgroud)
但结合izip
并chain.from_iterable
再次更快
In [2]: from itertools import chain, izip
In [3]: timeit "".join(chain.from_iterable(izip(l1, l2)))
10 loops, best of 3: 98.7 ms per loop
Run Code Online (Sandbox Code Playgroud)
chain(*
和之间也存在很大差异
chain.from_iterable(...
.
In [5]: timeit "".join(chain(*izip(l1, l2)))
1 loops, best of 3: 212 ms per loop
Run Code Online (Sandbox Code Playgroud)
没有像连接器这样的东西,传递一个总是会变慢,因为python将首先使用内容构建一个列表,因为它对数据进行两次传递,一次计算所需的大小,一个实际执行使用生成器无法实现的连接:
/* Here is the general case. Do a pre-pass to figure out the total
* amount of space we'll need (sz), and see whether all arguments are
* bytes-like.
*/
Run Code Online (Sandbox Code Playgroud)
此外,如果您有不同的长度字符串并且您不想丢失数据,则可以使用izip_longest:
In [22]: from itertools import izip_longest
In [23]: a,b = "hlo","elworld"
In [24]: "".join(chain.from_iterable(izip_longest(a, b,fillvalue="")))
Out[24]: 'helloworld'
Run Code Online (Sandbox Code Playgroud)
对于python 3,它被调用 zip_longest
但是对于python2,veedrac的建议到目前为止是最快的:
In [18]: %%timeit
res = bytearray(len(u) * 2)
res[::2] = u
res[1::2] = l
str(res)
....:
100 loops, best of 3: 2.68 ms per loop
Run Code Online (Sandbox Code Playgroud)
roo*_*oot 12
您也可以使用map
和执行此操作operator.add
:
from operator import add
u = 'AAAAA'
l = 'aaaaa'
s = "".join(map(add, u, l))
Run Code Online (Sandbox Code Playgroud)
输出:
'AaAaAaAaAa'
Run Code Online (Sandbox Code Playgroud)
映射的作用是从第一个iterable中获取每个元素,u
从第二个iterable中获取第一个元素,l
并应用作为第一个参数提供的函数add
.然后加入就加入了他们.
吉姆的答案很棒,但如果您不介意几种进口,这里是我最喜欢的选择:
from functools import reduce
from operator import add
reduce(add, map(add, u, l))
Run Code Online (Sandbox Code Playgroud)
很多这些建议都假定字符串长度相等.也许这涵盖了所有合理的用例,但至少在我看来,你似乎也想要容纳不同长度的字符串.或者我是唯一一个认为网格应该像这样工作的人:
u = "foobar"
l = "baz"
mesh(u,l) = "fboaozbar"
Run Code Online (Sandbox Code Playgroud)
一种方法是:
def mesh(a,b):
minlen = min(len(a),len(b))
return "".join(["".join(x+y for x,y in zip(a,b)),a[minlen:],b[minlen:]])
Run Code Online (Sandbox Code Playgroud)
我喜欢使用两个for
s,变量名称可以提示/提醒正在发生的事情:
"".join(char for pair in zip(u,l) for char in pair)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9775 次 |
最近记录: |