join([a1, a2, ..., aN], separator :: String)
返回
str(a1) + separator + str(a2) + separator + ... + str(aN)
例如,
join([1, 2, 3], '+') == '1+2+3'
我正在实现类似的功能,并且想知道执行此操作的最佳模式是什么?因为存在仅在分隔符不是最后一个元素时才添加分隔符的问题。
def join(l, sep):
out_str = ''
for i, el in enumerate(l):
out_str += '{}{}'.format(el, sep)
return out_str[:-len(sep)]
我对此很满意,但是有没有规范的方法? br />
#1 楼
Python中的字符串是不可变的,因此'string a' + 'string b'
必须制作第三个字符串以将它们组合在一起。假设您要克隆一个字符串,通过将每个项目添加到字符串中将获得\ $ O(n ^ 2)\ $时间,而不是\ $ O(n)\ $(如果它是一个列表)。 因此,使用分隔符连接迭代器的最佳方法是使用
str.join
。>>> ','.join('abcdef')
'a,b,c,d,e,f'
如果需要手动执行此操作,那么我会接受\ $ O(n ^ 2)\ $性能,并编写一些易于理解的内容。一种方法是获取第一个项目,并在每次之后添加一个分隔符和一个项目,例如:
def join(iterator, seperator):
it = map(str, iterator)
seperator = str(seperator)
string = next(it, '')
for s in it:
string += seperator + s
return string
评论
\ $ \ begingroup \ $
非常好,谢谢!是的,我对str.join有所了解,我只是在实现一些稍有不同的东西,并且想知道如何更好地做到这一点。我喜欢您在开始时使用next的方法!你知道我在哪里可以找到str.join的来源吗? Google没有帮助。
\ $ \ endgroup \ $
–fabian789
17年5月8日在11:28
\ $ \ begingroup \ $
@ fabian789 str.join的来源可能是这样。它看起来正确,并用C编写。
\ $ \ endgroup \ $
– Peilonrayz
17年5月8日在11:44
#2 楼
让我们逐步进行操作:def join(l, sep):
out_str = ''
for i, el in enumerate(l):
这里,为什么需要
enumerate
?您可以编写for el in l:
out_str += '{}{}'.format(el, sep)
.format
不是超级有效,还有其他方法。您可以看一下该问题,以获取有关性能的一些研究和基准。 return out_str[:-len(sep)]
如果
l = []
对len(sep) > 1
没有意义。 ''[:-1]
是有效的,并返回''
,因为python很不错,但它不是解决该限制情况的一种很好的方法。太好了。创建一个
iter
,先看第一个值,然后再添加其余值(如在其他答案中建议的那样)会更好。我也建议编写一些单元测试,以便您可以进行实施,并确信自己编写的内容仍然有效。
通常,您可以编写: br />
#3 楼
您可以通过多种方法来执行此操作,但是使用迭代器可能是一种不错的方法:在使用
next()
循环遍历其余部分之前,它与iterable的第一项有所不同。评论
\ $ \ begingroup \ $
试试[]
\ $ \ endgroup \ $
– njzk2
17年5月8日在15:58
#4 楼
由于join已经是Python的内置函数,因此建议不要创建名称相同的函数。我认为将函数重命名以排除可能的冲突是个好主意。评论
\ $ \ begingroup \ $
这只是错误的,help(join)导致NameError:未定义名称'join'。现在help(str.join)存在,但这不会引起任何冲突。
\ $ \ endgroup \ $
– Peilonrayz
20年7月8日在8:58
\ $ \ begingroup \ $
“由于join已经是Python的内置函数,建议不要创建一个同名的函数”-这也不适用于OP要求的上下文。这就是为什么他们首先添加“ reinvent-the-wheel”标签的原因:)
\ $ \ endgroup \ $
– Grajdeanu Alex
20年7月8日在9:31
评论
在Perl的联接中,分隔符是避免歧义的第一个参数。好的,通常在大多数语言和实现中,迭代地添加N个任意字符串将是O(N ^ 2),因为在每个循环中都需要调用malloc / realloc(),但是cPython对此有特殊情况,所以它只有N * O( 1)= O(N)。在本机Python中。 string.join或sep.join更快,因为它们是一个Python调用,而不是N。请参阅迭代字符串附加的时间复杂性实际上是O(n ^ 2)还是O(n)?
我比分隔符更喜欢定界符
@ bhathiya-perera“定界符”比“分隔符”更宽泛,也是技术术语。