Какой самый питонический способ соединить две строки вместе?
Например:
Входные данные:
u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
l = 'abcdefghijklmnopqrstuvwxyz'
Вывод:
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
python
string
python-2.7
python-3.x
Брэндон Део
источник
источник
Ответы:
Для меня наиболее питоническим * способом является следующий, который в значительной степени делает то же самое, но использует
+
оператор для объединения отдельных символов в каждой строке:Это также быстрее, чем использование двух
join()
вызовов:Существуют более быстрые подходы, но они часто запутывают код.
Примечание. Если две входные строки не одинаковой длины, более длинная будет усечена, так как
zip
перебор прекращается в конце более короткой строки. В этом случае вместоzip
одного следует использоватьzip_longest
(izip_longest
в Python 2) изitertools
модуля, чтобы убедиться, что обе строки полностью исчерпаны.* Приведу цитату из «Дзен Python» : удобочитаемость имеет значение .
Pythonic = читабельность для меня;
i + j
просто визуально легче анализируется, по крайней мере, для моих глаз.источник
"".join([i + j for i, j in zip(l1, l2)])
и это, безусловно , самый быстрый"".join(map("".join, zip(l1, l2)))
даже быстрее, хотя и не обязательно более питоническим.Быстрая альтернатива
По-другому:
Вывод:
скорость
Похоже, это быстрее:
чем самое быстрое решение:
Также для больших струн:
Python 3.5.1.
Вариация для струн разной длины
Более короткий определяет длину (
zip()
эквивалент)Вывод:
Более длинный определяет длину (
itertools.zip_longest(fillvalue='')
эквивалент)Вывод:
источник
С
join()
иzip()
.источник
''.join(itertools.chain.from_iterable(zip(u, l)))
zip
остановится, когда более короткий список будет полностью повторен.itertools.zip_longest
можно использовать, если это станет проблемой.В Python 2 гораздо более быстрый способ делать что-либо, примерно в 3 раза быстрее, чем нарезка списка для небольших строк и в ~ 30 раз для длинных, - это
Однако это не сработает на Python 3. Вы могли бы реализовать что-то вроде
но к тому времени вы уже потеряли преимущество над разрезанием списков для небольших строк (это все еще в 20 раз выше скорости для длинных строк), и это еще не работает даже для символов, отличных от ASCII.
FWIW, если будут делать это на массивных струнах и нуждается в каждом цикле, и по какой - то причине должен использовать строки Python ... Вот как это сделать:
Поможет и специальный корпус, обычный для более мелких типов. FWIW, это всего в 3 раза больше скорости нарезки списка для длинных строк и в 4–5 раз медленнее для небольших строк.
В любом случае я предпочитаю
join
решения, но, поскольку время было упомянуто в другом месте, я подумал, что могу присоединиться.источник
Если вам нужен самый быстрый способ, вы можете объединить itertools с
operator.add
:Но комбинирование
izip
иchain.from_iterable
снова быстрееТакже существует существенная разница между
chain(*
иchain.from_iterable(...
.Нет такой вещи, как генератор с соединением, передача одного всегда будет медленнее, поскольку python сначала создаст список, используя контент, потому что он выполняет два прохода по данным, один для определения необходимого размера, а другой для фактического выполнения соединение, которое невозможно с помощью генератора:
join.h :
Также, если у вас есть строки разной длины и вы не хотите терять данные, вы можете использовать izip_longest :
Для Python 3 это называется
zip_longest
Но для python2 предложение veedrac, безусловно, самое быстрое:
источник
list
?? не нужен"".join(list(...))
дает мне 6.715280318699769 и timeit"".join(starmap(...))
дает мне 6.46332361384313"".join(list(starmap(add, izip(l1,l2))))
медленнее, чем"".join(starmap(add, izip(l1,l2)))
. Я запускаю тест на своей машине в python 2.7.11 и в python 3.5.1 даже в виртуальной консоли www.python.org с python 3.4.3, и все говорят то же самое, и я запускаю его пару раз и всегда то же самоеВы также можете сделать это, используя
map
иoperator.add
:Выход :
Что делает map, так это то, что она берет каждый элемент из первой итерации
u
и первые элементы из второй итерацииl
и применяет функцию, предоставленную в качестве первого аргументаadd
. Тогда присоединяйся просто присоединяйся к ним.источник
Ответ Джима отличный, но вот мой любимый вариант, если вы не возражаете против парочки импорта:
источник
Многие из этих предложений предполагают, что строки имеют одинаковую длину. Возможно, это покрывает все разумные варианты использования, но, по крайней мере, мне кажется, что вы также можете разместить строки разной длины. Или я единственный, кто думает, что сетка должна работать примерно так:
Один из способов сделать это:
источник
Мне нравится использовать два
for
s, имена переменных могут дать подсказку / напоминание о том, что происходит:источник
Просто чтобы добавить еще один, более простой подход:
источник
Чувствует себя немного непитоничным, чтобы не рассматривать здесь ответ с двойным списком, чтобы обрабатывать n строку с усилием O (1):
где
all_strings
- список строк, которые вы хотите перемежать. В вашем случаеall_strings = [u, l]
. Пример полного использования будет выглядеть так:Как и многие ответы, самый быстрый? Наверное, нет, но просто и гибко. Кроме того, без особых дополнительных сложностей, это немного быстрее, чем принятый ответ (в общем, добавление строк в python немного медленнее):
источник
Потенциально быстрее и короче, чем текущее ведущее решение:
Стратегия с точки зрения скорости - делать как можно больше на высшем уровне. То же самое исправление zip_longest () для неровных строк, и оно будет выходить из того же модуля, что и chain (), так что не стоит мне слишком много очков!
Другие решения, которые я придумал по ходу дела:
источник
Вы можете использовать 1
iteration_utilities.roundrobin
или
ManyIterables
класс из того же пакета:1 Это из библиотеки третьей стороной я написал:
iteration_utilities
.источник
Я бы использовал zip (), чтобы получить понятный и простой способ:
источник