如何在 Python 中反转字符串?

2024-11-20 08:43:00
admin
原创
155
摘要:问题描述:reversePython 的对象没有内置方法str。如何反转字符串?解决方案 1:使用切片:>>> 'hello world'[::-1] 'dlrow olleh' 切片符号采用 的形式[start:stop:step]。在本例中,我们省略了start和stop位置,因为我们想...

问题描述:

reversePython 的对象没有内置方法str。如何反转字符串?


解决方案 1:

使用切片:

>>> 'hello world'[::-1]
'dlrow olleh'

切片符号采用 的形式[start:stop:step]。在本例中,我们省略了startstop位置,因为我们想要整个字符串。我们还使用step = -1,这意味着“从右向左反复移动 1 个字符”。

解决方案 2:

实现字符串反向函数的最佳方法是什么?

我自己对这个问题的经验是学术性的。但是,如果你是一个寻求快速答案的专业人士,请使用以下步骤-1

>>> 'a string'[::-1]
'gnirts a'

或者更易读(但由于方法名称查找和 join 在给定迭代器时形成列表的事实,速度较慢)str.join,:

>>> ''.join(reversed('a string'))
'gnirts a'

或者为了提高可读性和可重用性,将切片放在函数中

def reversed_string(a_string):
    return a_string[::-1]

进而:

>>> reversed_string('a_string')
'gnirts_a'

详细解释

如果您对学术论述感兴趣,请继续阅读。

Python 的 str 对象中没有内置的反向函数。

以下是关于 Python 字符串你应该知道的几件事:

  1. 在 Python 中,字符串是不可变的。更改字符串并不会修改该字符串。它会创建一个新的字符串。

  2. 字符串是可切片的。切片字符串会以给定的增量从字符串中的一个点向后或向前到另一个点生成一个新的字符串。它们采用切片符号或下标中的切片对象:

string[subscript]

下标通过在括号内包含冒号来创建切片:

    string[start:stop:step]

要在括号外创建切片,您需要创建一个切片对象:

    slice_obj = slice(start, stop, step)
    string[slice_obj]

一种可读的方法:

虽然''.join(reversed('foo'))可读性强,但它需要在另一个被调用函数上调用字符串方法str.join,这可能相对较慢。让我们把它放在一个函数中——我们稍后再讨论它:

def reverse_string_readable_answer(string):
    return ''.join(reversed(string))

最高效的方法:

使用反向切片会更快:

'foo'[::-1]

但是,对于不太熟悉切片或原作者意图的人来说,我们如何才能使其更具可读性和可理解性呢?让我们在下标符号之外创建一个切片对象,给它一个描述性的名称,并将其传递给下标符号。

start = stop = None
step = -1
reverse_slice = slice(start, stop, step)
'foo'[reverse_slice]

作为函数实现

为了真正将其实现为一个函数,我认为只需使用一个描述性名称在语义上就足够清楚了:

def reversed_string(a_string):
    return a_string[::-1]

使用方法很简单:

reversed_string('foo')

你的老师可能想要的是:

如果您有一位导师,他们可能希望您从一个空字符串开始,然后从旧字符串构建一个新字符串。您可以使用 while 循环通过纯语法和文字来执行此操作:

def reverse_a_string_slowly(a_string):
    new_string = ''
    index = len(a_string)
    while index:
        index -= 1                    # index = index - 1
        new_string += a_string[index] # new_string = new_string + character
    return new_string

从理论上讲,这是不好的,因为请记住,字符串是不可变的- 因此每次当你在 上添加一个字符时new_string,理论上每次都会创建一个新的字符串!但是,CPython 知道如何在某些情况下优化这一点,这个简单的例子就是其中之一。

最佳实践

理论上更好的方法是将子字符串收集到一个列表中,然后稍后再将它们加入:

def reverse_a_string_more_slowly(a_string):
    new_strings = []
    index = len(a_string)
    while index:
        index -= 1                       
        new_strings.append(a_string[index])
    return ''.join(new_strings)

但是,正如我们将在下面的 CPython 时间中看到的,这实际上需要更长的时间,因为 CPython 可以优化字符串连接。

时间安排

具体时间如下:

>>> a_string = 'amanaplanacanalpanama' * 10
>>> min(timeit.repeat(lambda: reverse_string_readable_answer(a_string)))
10.38789987564087
>>> min(timeit.repeat(lambda: reversed_string(a_string)))
0.6622700691223145
>>> min(timeit.repeat(lambda: reverse_a_string_slowly(a_string)))
25.756799936294556
>>> min(timeit.repeat(lambda: reverse_a_string_more_slowly(a_string)))
38.73570013046265

CPython 优化了字符串连接,而其他实现可能不会:

... 对于 a += b 或 a = a + b 形式的语句,不要依赖 CPython 就地字符串连接的有效实现。这种优化即使在 CPython 中也很脆弱(它只适用于某些类型),并且在未使用引用计数的实现中根本不存在。在库的性能敏感部分,应改用 ''.join() 形式。这将确保连接在各种实现中以线性时间发生。

解决方案 3:

@Paolo 的s[::-1]方法最快;较慢的方法(可能更具可读性,但这是有争议的)是''.join(reversed(s))

解决方案 4:

这个答案有点长,包含 3 个部分:现有解决方案的基准为什么这里的大多数解决方案是错误的我的解决方案

现有的答案只有在忽略 Unicode 修饰符/字素簇的情况下才是正确的。我稍后会处理这个问题,但首先看一下一些反转算法的速度:

在此处输入图片描述

注意:我所说的list_comprehension应该称为slicing

slicing         : min:   0.6μs, mean:   0.6μs, max:    2.2μs
reverse_func    : min:   1.9μs, mean:   2.0μs, max:    7.9μs
reverse_reduce  : min:   5.7μs, mean:   5.9μs, max:   10.2μs
reverse_loop    : min:   3.0μs, mean:   3.1μs, max:    6.8μs

在此处输入图片描述

slicing         : min:   4.2μs, mean:   4.5μs, max:   31.7μs
reverse_func    : min:  75.4μs, mean:  76.6μs, max:  109.5μs
reverse_reduce  : min: 749.2μs, mean: 882.4μs, max: 2310.4μs
reverse_loop    : min: 469.7μs, mean: 577.2μs, max: 1227.6μs

您可以看到,切片(reversed = string[::-1])的时间在所有情况下都是最短的(即使在修复我的拼写错误之后)。

字符串反转

如果你真的想以常识性的方式反转一个字符串,那么它要复杂得多。例如,以下面的字符串为例(棕色手指指向左边,黄色手指指向上面)。这是两个字素,但有 3 个 unicode 码点。额外的一个是皮肤修饰符。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1120  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   75  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   66  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   76  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   70  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用