我意识到如果你有一个可迭代的,你应该总是使用.join(iterable)
而不是for x in y: str += x
。但是,如果只有固定数量的变量尚未包含在迭代中,那么仍然使用.join()
建议的方式吗?
例如我有
user = 'username'
host = 'host'
我应该
ret = user + '@' + host
或
ret = '@'.join([user, host])
从表现的角度来看,我并不是那么多,因为两者都是微不足道的。但我读到这里的人说总是使用.join()
,我想知道是否有任何特殊原因,或者使用.join()
通常是个好主意。
答案 0 :(得分:29)
如果您正在创建类似的字符串,通常需要使用字符串格式:
>>> user = 'username'
>>> host = 'host'
>>> '%s@%s' % (user, host)
'username@host'
Python 2.6添加了另一种形式,它不依赖于运算符重载并具有一些额外的功能:
>>> '{0}@{1}'.format(user, host)
'username@host'
作为一般准则,大多数人只有在字符串中添加两个字符串时才会对字符串使用+
。对于更多部分或更复杂的字符串,它们要么使用字符串格式,如上所述,要么在列表中组合元素并将它们连接在一起(特别是如果涉及任何形式的循环。)使用str.join()
的原因是添加字符串在一起意味着创建一个新字符串(并可能会破坏旧字符串)每次添加。 Python有时可以优化它,但str.join()
很快变得更清晰,更明显,更快。
答案 1 :(得分:13)
我接受这个问题的意思是:“这样做可以:”
ret = user + '@' + host
..答案是肯定的。这很好。
当然,你应该知道你可以用Python做的很酷的格式化东西,你应该知道,对于长列表,“加入”是要走的路,但是对于像这样的简单情况,什么你有完全正确的。它简单明了,性能不会成为问题。
答案 2 :(得分:9)
(我很确定所有指向字符串格式的人都完全错过了这个问题。)
通过构造数组并加入它来创建字符串仅出于性能原因。除非你需要这种性能,或者除非它恰好是实现它的自然方式,否则没有任何好处,而不是简单的字符串连接。
说'@'.join([user, host])
不直观。这让我很奇怪:他为什么要这样做?它有什么微妙之处;有没有可能有多个'@'的情况?当然,答案是否定的,但是得出这个结论需要花费更多时间,而不是以自然的方式写出来。
不要仅仅为了避免字符串连接而扭曲你的代码;它没有任何内在错误。加入数组只是一种优化。
答案 3 :(得分:7)
我要注意,在重读Python普通样式PEP PEP-8 Style Guide for Python Code的一部分之前,我总是倾向于使用就地连接。
- 代码应该以不会对其他方式不利的方式编写 Python的实现(PyPy,Jython,IronPython,Pyrex,Psyco, 等等)。 例如,不要依赖CPython的高效实现 形式为a + = b或a = a + b的语句的就地字符串连接。 这些语句在Jython中运行得更慢。在性能敏感 库的一部分,应该使用'.join()形式。这个 将确保连接在各种线性时间内发生 的实施方式。
顺便说一句,我一直在转向使用连接的做法,这样当效率更加关键时,我可以将这种习惯保留为更自动的习惯。
所以我会投票支持:
ret = '@'.join([user, host])
答案 4 :(得分:1)
我使用下一个:
ret = '%s@%s' % (user, host)
答案 5 :(得分:0)
基于两个方面,我建议在串联时不要使用join()
:
关于第一个方面,这是一个示例:
import timeit
s1 = "Flowers"
s2 = "of"
s3 = "War"
def join_concat():
return s1 + " " + s2 + " " + s3
def join_builtin():
return " ".join((s1, s2, s3))
print("Join Concatenation: ", timeit.timeit(join_concat))
print("Join Builtin: ", timeit.timeit(join_builtin))
输出:
$ python3 join_test.py
Join Concatenation: 0.40386943198973313
Join Builtin: 0.2666833929979475
考虑到巨大的数据集(数百万行)及其处理(每行130毫秒),这实在太多了。
第二个方面确实更加优雅。