Скорость против безопасности против совместимости над методами конкатенации строк в Python

Подобные вопросы были перенесены (хорошее сравнение скорости) на этом же subject. Надеюсь, это другой вопрос, и он обновлен до Python 2.6 и 3.0.

Пока что я считаю, что более быстрый и наиболее совместимый метод (среди разных версий Python) - это простой простой знак +:

text = "whatever" + " you " + SAY

Но я все время слышу и читаю, это небезопасно и / или не рекомендуется.

Я даже не уверен, сколько существует методов для управления строками! Я мог сосчитать только около 4: есть интерполяция и все ее подпараметры, такие как % и format, а затем есть простые, join и +.

Наконец, новый подход к форматированию строк, который используется в format, определенно не подходит для обратной совместимости, в то же время делая % не подходящим для прямой совместимости. Но следует ли его использовать для каждой строковой обработки, включая каждую конкатенацию, всякий раз, когда мы ограничиваемся только 3.x?

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

Спасибо.

edit: Я не уверен, что должен принимать ответ, если я не чувствую, что он действительно отвечает на вопрос ... Но я считаю, что все они 3 вместе делают правильную работу.

Ответ Даниэля, за который проголосовали больше всего, я бы предпочел принять, если бы не «примечание». Я категорически не согласен с «конкатенация строго использует оператор + для конкатенации строк» ​​, потому что, например, join также выполняет конкатенацию строк, и для этого мы можем создать любую произвольную библиотеку.

Все текущие 3 ответа ценны, и я бы предпочел получить какой-нибудь ответ, смешивающий их все. Хотя никто из добровольцев этого не делает, я думаю, что, выбрав тот, за который проголосовали меньше (но он гораздо шире, чем у THC4k, что больше похоже на большой и очень желанный комментарий), я могу привлечь внимание и к другим.


person cregox    schedule 07.05.2010    source источник
comment
Где вы читаете, что + небезопасно и / или не рекомендуется?   -  person John Machin    schedule 08.05.2010
comment
@John, например, прочтите 2 ответа ниже. Оба они не рекомендуют использовать +.   -  person cregox    schedule 08.05.2010
comment
Возможно, я интерпретировал слово «целесообразно» иначе, чем вы. Во всяком случае, вы это писали раньше, чем были написаны ответы. Также ни один из ответов не указывает на то, что += стал быстрее в более поздних версиях Pythons. Где вы читаете, что + небезопасно?   -  person John Machin    schedule 08.05.2010
comment
@John, это потому, что общий здравый смысл в них скорее всего построен из других мест. По скорости смотрите по второй ссылке. Наконец, эта безопасная часть была больше на слуху. Некоторые осведомленные ребята здесь на работе сказали мне, что с ним проще выполнять инъекцию строк. Но я не смог найти много информации по этому поводу. Во всяком случае, вы знаете, это не википедия! ;П   -  person cregox    schedule 11.05.2010
comment
Формат поддерживается начиная с python 2.6 и более поздних версий.   -  person kon psych    schedule 15.06.2014


Ответы (3)


Использование + допустимо, но не в том случае, если оно автоматизировано:

a + small + number + of + strings + "is pretty fast"

но это может быть очень медленным:

s = ''
for line in anything:
   s += line 

Используйте вместо этого:

s = ''.join([line for line in anything])

Есть плюсы и минусы использования + против '%s%line' - использование + здесь не даст результата:

s = 'Error - unexpected string' + 42

Если вы хотите, чтобы он генерировал исключение или молча делал что-то необычное, зависит от вашего использования.

person wisty    schedule 07.05.2010
comment
Но вы говорите, что join работает лучше, чем + даже для небольших строк? Я бы рискнул сказать, что почти каждое программное обеспечение будет иметь почти каждую строку кода с конкатенацией небольших строк ... Но люди, кажется, говорят об этом так, будто это наоборот. - person cregox; 08.05.2010
comment
s = ''.join([line for line in anything]) имеет бессмысленный цикл для создания бессмысленного списка - ›s=''.join(anything) - person Jochen Ritzel; 08.05.2010
comment
@Cawas, для небольшого количества строк реальной разницы нет. Для большого количества (скажем, 100) маленьких строк (когда конечным результатом является большая строка) соединение выполняется быстрее. Оба должны быть очень быстрыми. Читаемость важнее. - person wisty; 09.05.2010
comment
@ THC4k, это не бессмысленно, если anything итератор. ''.join нужен список, а не итератор. - person wisty; 09.05.2010

В качестве примечания: на самом деле речь идет о построении строк, а не о конкатенации как таковой, поскольку конкатенация строго использует оператор + для объединения строк друг за другом.

  • + (конкатенация) - как правило, неэффективно, но для некоторых людей может быть легче читать, используйте только тогда, когда удобочитаемость является приоритетом, а производительность нет (простые сценарии, одноразовые сценарии, не требующий высокой производительности код)
  • join (построение строки из последовательности строк) - используйте это, если у вас есть последовательность строк, которую нужно объединить с помощью общего символа (или вообще без символа, если вы хотите использовать пустой строка '' для присоединения)
  • % и format (интерполяция) - в основном каждая другая операция должна использовать тот из них, который подходит, выберите, какой оператор / функция подходит, в зависимости от того, какую версию Python вы хотите поддерживать в течение всего времени существования кода. (используйте % для 2.x и format для 3.x)
person Daniel DiPaolo    schedule 07.05.2010
comment
Что ж, мое внимание здесь сосредоточено только на конкатенации, я действительно не хочу вдаваться в форматирование строк и все такое. Но, честно говоря, говоря о format и % других функциях, лучше было бы сказать "строительство", а я даже не подумал об этом слове. Не знаю, ты все еще думаешь, что лучше я поменяю название? - person cregox; 08.05.2010
comment
Что касается скорости конкатенации, взгляните на ту ссылку, которую я дал для сравнения скорости. Вы удивитесь. Кроме того, я не хочу обсуждать здесь дизайн / удобочитаемость. Думаю, в данном случае это очень субъективно. - person cregox; 08.05.2010

Проблема с + для строк такая же, как и во многих других языках: каждый раз, когда вы расширяете строку, она копируется. Итак, чтобы построить одну строку из 100 подстрок, Python копирует каждый из 99 шагов.

И на это нужно время:

# join 100 pretty short strings
python -m timeit -s "s = ['pretty short'] * 100" "t = ''.join(s)"
100000 loops, best of 3: 4.18 usec per loop

# same thing, 6 times slower
python -m timeit -s "s = ['pretty short'] * 100" "t = ''" "for x in s:" " t+=x"
10000 loops, best of 3: 30 usec per loop
person Jochen Ritzel    schedule 08.05.2010