Дополнительно
Обратное преобразование строки в Python
В Python нет встроенной функции reverse
для объекта str
. Как лучше всего реализовать этот метод?
Если ответ будет очень кратким, пожалуйста, расскажите о его эффективности. Например, преобразуется ли объект str
в другой объект и т.д.
1281
20
Как насчет:
Это синтаксис extended slice. Он работает по принципу
[begin:end:step]
- оставляя begin и end без внимания и указывая шаг -1, он переворачивает строку.@Paolo'
s[::-1]
- самый быстрый; более медленный подход (возможно, более читабельный, но это спорно) -''.join(reversed(s))
.Мой собственный опыт в этом вопросе академический. Однако, если вы профессионал, ищущий быстрый ответ, используйте фрагмент, который шагает по
-1
:или более читаемо (но медленнее из-за поиска имени метода и того факта, что объединение формирует список при предоставлении итератора),
str.join
:или для удобочитаемости и повторного использования, поместите срез в функцию
а потом:
Более длинное объяснение
Если вы заинтересованы в академической экспозиции, пожалуйста, продолжайте читать.
Вот пара вещей о строках Python, которые вы должны знать:
В Python струны неизменны . Изменение строки не изменяет строку. Это создает новый.
Струны нарезаются. Нажатие строки дает вам новую строку из одной точки в строке, назад или вперед, в другую точку с заданными приращениями. Они берут нотацию среза или объект среза в нижнем индексе:
Нижний индекс создает срез, включая двоеточие в фигурных скобках:
Чтобы создать срез вне скобок, вам нужно создать объект среза:
Читаемый подход:
Хотя
' .join (reversed ('foo'))
читаем, для этого требуется вызвать строковый методstr.join
для другой вызываемой функции, которая может быть относительно медленной. Давайте включим это в функцию - мы вернемся к этому:Самый эффективный подход:
Гораздо быстрее использовать обратный срез:
Но как мы можем сделать это более читабельным и понятным для кого-то, кто менее знаком с ломтиками или намерением оригинального автора? Давайте создадим объект среза за пределами обозначения индекса, дадим ему описательное имя и передадим его в обозначение индекса.
Реализовать как функцию
Чтобы реально реализовать это как функцию, я думаю, что это достаточно семантически ясно, чтобы просто использовать описательное имя:
И использование просто:
Чего, вероятно, хочет ваш учитель:
Если у вас есть инструктор, они, вероятно, хотят, чтобы вы начали с пустой строки и создали новую строку из старой. Вы можете сделать это с помощью чистого синтаксиса и литералов, используя цикл while:
Это теоретически плохо, потому что, помните, струны неизменны - поэтому каждый раз, когда кажется, что вы добавляете символ в свою
new_string
, он теоретически создает новую строку каждый раз! Тем не менее, CPython знает, как оптимизировать это в определенных случаях, одним из которых является этот тривиальный случай.Лучшая практика
Теоретически лучше собрать ваши подстроки в списке и присоединиться к ним позже:
Однако, как мы увидим в приведенных ниже таймингах для CPython, это на самом деле занимает больше времени, поскольку CPython может оптимизировать конкатенацию строк.
Сроки
Вот тайминги:
CPython оптимизирует конкатенацию строк, тогда как другие реализации не могут:
Быстрый ответ (TL; DR)
Подробный ответ
Фон
Этот ответ предоставлен для решения следующей проблемы от @odigity:
Проблема
Решение
Подводные камни
string.reverse ()
string.reverse ()
, чтобы избежать нотации срезов.print 'coup_ate_grouping' [-4:] ## = > 'пинг'
print 'coup_ate_grouping' [-4: -1] ## = > 'булавка'
print 'coup_ate_grouping' [-1] ## = > 'Г'
[-1]
могут сбить некоторых разработчиковОбоснование
У Python есть особые обстоятельства, о которых следует знать: строка является типом iterable.
Одним из обоснований исключения метода
string.reverse ()
является стимулирование разработчиков python использовать силу этого особого обстоятельства.В упрощенном выражении это просто означает, что каждый отдельный символ в строке может легко управляться как часть последовательного расположения элементов, как массивы в других языках программирования.
Чтобы понять, как это работает, обзор example02 может дать хороший обзор.
Example02
Вывод
Когнитивная нагрузка, связанная с пониманием того, как в python работает запись срезов, действительно может быть слишком большой для некоторых пользователей и разработчиков, которые не хотят вкладывать много времени в изучение язык.
Тем не менее, как только основные принципы поняты, сила этого подхода над методами манипулирования фиксированными струнами может быть весьма благоприятной.
Для тех, кто думает иначе, существуют альтернативные подходы, такие как лямбда-функции, итераторы или простые одноразовые объявления функций.
При желании разработчик может реализовать свой собственный метод string.reverse (), однако полезно понять обоснование этого аспекта питона.
Смотрите также
Менее озадачивающий способ взглянуть на это будет:
На английском языке [-1 :: - 1] читается как:
Существующие ответы верны только в том случае, если игнорируются модификаторы Unicode / кластеры графемы. Я разберусь с этим позже, но сначала взгляну на скорость некоторых алгоритмов реверсирования
[![введите описание изображения здесь][1]][1]
[![введите описание изображения здесь][2]][2]
Вы можете видеть, что время для понимания списка (
reversed = string [:: -1]
) во всех случаях является самым низким (даже после исправления моей опечатки).Реверсация струн
Если вы действительно хотите изменить строку в здравом смысле, это НАМНОГО сложнее. Например, возьмите следующую строку (коричневый палец, указывающий влево, [желтый палец, указывающий вверх](https:// emojipedia.org/white-up-pointing-backhand-index/)). Это две графемы, но 3 кодовых точки Unicode. Дополнительным является модификатор кожи.
Но если вы измените его любым из указанных методов, вы получите коричневый палец, указывающий вверх, желтый палец, указывающий влево. Причина этого заключается в том, что «коричневый» модификатор цвета все еще находится посередине и применяется ко всему, что есть до него. Итак, у нас есть
а также
Unicode Grapheme Clusters немного сложнее, чем просто кодовые точки модификатора. К счастью, есть библиотека для обработки graphemes:
и, следовательно, правильный ответ будет
который также является безусловно самым медленным:
Код
1. используя нотацию среза
2. с помощью функции revid ()
3. с использованием рекурсии
Это также интересный способ:
или аналогичный:
Еще один более «экзотический» способ с использованием byterarray, который поддерживает .reverse ()
будет производить:
Обращение строки в python без использования reversed() или [::-1]
Рекурсивный метод:
пример:
Здесь нет фантазии:
Все вышеперечисленные решения идеальны, но если мы попытаемся изменить строку с помощью цикла для python, это станет немного сложно, поэтому мы можем изменить строку, используя цикл
Я надеюсь, что этот будет полезен для кого-то.
Вот мой путь:
Это работает путем циклирования строки и присвоения ее значений в обратном порядке другой строке.
Есть много способов изменить строку, но я также создал еще один просто для удовольствия. Я думаю, что этот подход не так уж и плох.
Этот класс использует магические функции питона для изменения строки:
Output
Ссылка
Вот один без
[:: -1]
илиreversed
(для учебных целей):Вы можете использовать
+ =
, чтобы объединить строки, ноjoin ()
быстрее.Это простая и значимая обратная функция, простая для понимания и кодирующая