Ответ 1
Итак, прежде всего, давайте сломаем, почему это работает.
>>> string1 = "foo"
>>> string2 = "bar"
>>> string1.join(string2)
'bfooafoor'
Это операция поместить string1
между каждым элементом (символом) string2
.
Таким образом, замена пустой строки делает что-то интересное, она подсчитывает пробел между пустыми символами как пустую строку и, следовательно, выполняет по существу одну и ту же задачу, кроме как с дополнительным разделителем в начале и в конце:
>>> string2.replace('', string1)
'foobfooafoorfoo'
Таким образом, нарезка из них дает тот же результат, что и str.join()
:
>>> string2.replace('', string1)[len(string1):-len(string1)]
'bfooafoor'
Очевидно, что это решение намного, гораздо менее читаемо, чем str.join()
, и поэтому я всегда рекомендую против него. str.join()
также был разработан, чтобы быть эффективным на всех платформах. Замена пустой строки может быть намного менее эффективной для некоторых версий Python (я не знаю, может ли это быть, но это возможно - так же, как повторное конкатенация достаточно быстро в CPython, но это не обязательно в другом месте.)
Я даже не могу найти что-либо в документации, которая предполагает, что это поведение замены пустой строки должно функционировать таким образом, docs для str.replace()
просто скажите:
Возвращает копию строки со всеми вхождениями подстроки old, замененной на новую. Если задан параметр необязательного аргумента, заменяются только первые экземпляры счетчика.
Я не вижу причин, по которым мы должны предполагать, что пробелы между буквами должны считаться появлением пустой строки (возможно, вы могли бы поместить бесконечные пустые строки в любом месте строки), и как таковая, полагаясь на это поведение, быть плохой идеей.
Эта операция также довольно редка - более распространено иметь последовательность строк для объединения - объединение отдельных символов строки - это не то, что я лично должен был делать часто.
Интересно, что этот x.replace("", y)
представляется специальным в источнике Python:
2347 /* Algorithms for different cases of string replacement */
2348
2349 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
2350 Py_LOCAL(PyStringObject *)
2351 replace_interleave(PyStringObject *self,
2352 const char *to_s, Py_ssize_t to_len,
2353 Py_ssize_t maxcount)
2354 {
...
Возможно, этот специальный корпус заставляет его работать хорошо. Опять же, как это не упоминается в документации, это детализация реализации, и если предположить, что она будет работать так же быстро (или вообще) в других версиях Python, это будет ошибкой.