Python .join или конкатенация строк - PullRequest
23 голосов
/ 12 ноября 2010

Я понимаю, что если у вас есть итерация, вы всегда должны использовать .join(iterable) вместо for x in y: str += x. Но если существует только фиксированное количество переменных, которые еще не включены в итерацию, то по-прежнему ли рекомендуется использовать .join()?

Например, у меня есть

user = 'username'
host = 'host'

я должен сделать

ret = user + '@' + host

или

ret = '@'.join([user, host])

Я не так сильно спрашиваю с точки зрения производительности, так как оба будут довольно тривиальными. Но я читал здесь людей, которые говорят, что всегда используют .join(), и мне было интересно, есть ли какая-то конкретная причина для этого или просто хорошая идея использовать .join().

Ответы [ 5 ]

29 голосов
/ 12 ноября 2010

Если вы создаете такую ​​строку, вы обычно хотите использовать форматирование строки:

>>> 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() быстро становится понятнее, очевиднее и значительно быстрее.

13 голосов
/ 20 ноября 2010

Я принимаю вопрос, чтобы означать: «Это нормально делать это:»

ret = user + '@' + host

.. и ответ - да.Это прекрасно.

Вы, конечно, должны знать о классных возможностях форматирования, которые вы можете делать в Python, и вы должны знать, что для длинных списков "соединение" - это путь, нодля простой ситуации, подобной этой, то, что у вас есть, совершенно верно.Это просто и понятно, и производительность не будет проблемой.

9 голосов
/ 12 ноября 2010

(Я почти уверен, что все люди, указывающие на форматирование строк, полностью упускают вопрос.)

Создание строки путем создания массива и присоединения к нему только из соображений производительности. Если вам не нужна эта производительность или если она не является естественным способом ее реализации, то нет ничего лучше, чем простая конкатенация строк.

Сказать '@'.join([user, host]) не интуитивно. Это заставляет меня задуматься: зачем он это делает? Есть ли в этом какие-то тонкости; есть ли случай, когда может быть более одного '@'? Ответ, конечно, отрицательный, но для того, чтобы прийти к такому выводу, требуется больше времени, чем если бы он был написан естественным образом.

Не искажайте ваш код просто для того, чтобы избежать конкатенации строк; в этом нет ничего плохого. Объединение массивов - это просто оптимизация.

7 голосов
/ 12 марта 2012

Я просто отмечу, что я всегда имел тенденцию использовать конкатенацию на месте, пока не перечитал часть общего стиля Python PEP Руководство по стилю PEP-8 для кода Python .

  • Код должен быть написан так, чтобы не мешать другим реализации Python (PyPy, Jython, IronPython, Pyrex, Psyco, и тому подобное). Например, не полагайтесь на эффективную реализацию CPython конкатенация строк на месте для операторов в форме a + = b или a = a + b. Эти утверждения работают медленнее в Jython. В производительности чувствительны части библиотеки, вместо этого следует использовать форму '' .join (). это будет гарантировать, что конкатенация происходит в линейное время между различными Реализации.

Исходя из этого, я перешел к практике использования объединений, чтобы я мог сохранить привычку как более автоматическую практику, когда эффективность чрезвычайно важна.

Итак, я поставлю свой голос за:

ret = '@'.join([user, host])
1 голос
/ 12 ноября 2010

Я использую следующее:

ret = '%s@%s' % (user, host)
...