三种Python反转字符串方法的性能差距

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理

本文章来自腾讯云 作者:Python知识大全

想要学习Python?有问题得不到第一时间解决?来看看这里“1039649593”满足你的需求,资料都已经上传至文件中,可以自行下载!还有海量最新2020python学习资料。
点击查看

在这里插入图片描述

反转Python字符串的三种主要方法:“切片”,反转迭代和经典的就地反转算法。

在Python中反转字符串的最佳方法是什么?当然,在日常编程中并不经常使用字符串反转,但是这是一个受欢迎的面试问题:

#你有这个:
'TURBO'

#而您想要的是
'OBRUT'

这个问题的一种变化是编写一个函数,该函数检查给定的字符串是否是回文,

def is_palindrome(string):
    reversed_string = # ???
    return string == reversed_string

>>> is_palindrome('TACOCAT')
True
>>> is_palindrome('TURBO')
False

显然,我们需要弄清楚如何反转字符串以is_palindrome在Python中实现此功能应该怎么做?

Python的str字符串对象没有内置.reverse()方法,就像其他语言(例如Java或C#)进入Python时所呈现的那样,以下方法将会报错:

>>> 'TURBO'.reverse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'reverse'

这次我们将介绍在Python中反转字符串的三种主要方法以及比较三者之间的性能差距。

第一种:使用“ [::-1]”切片技巧反转Python字符串

字符串遵循Python中的序列协议。并且所有序列都支持一个强大的功能,称为切片。您可以将切片视为方括号索引语法的扩展。

它包括一个特殊情况,其中用“ [::-1]” 切片序列会产生反向副本。因为Python字符串是序列,所以这是获取字符串的反向副本的快速简便的方法:

>>>  'TURBO' [:: - 1 ]
'OBRUT'

可以将此切片表达式写到一个函数中,让代码的作用更加明显:

defreverse_string1(s):
    """Return a reversed copyof `s`"""
    returns[::-1]
 
>>>reverse_string1('TURBO')
'OBRUT'

新手第一次遇到列表切片时可能很难理解列表切片。

我觉得使用Python的切片功能来反转字符串是一个不错的解决方案,但是对于初学者来说可能很难理解。

继续…

第二种:使用reversed()和反转Python字符串str.join()

使用reverse()内置的reverse迭代来反转字符串。从而得到一个反向迭代器,然后循环遍历字符串中的元素。例如:

>>>foreleminreversed('TURBO'):
...     print(elem)
O
B
R
U
T

使用reversed()不会修改原始字符串(由于Python中的字符串是不可变的,因此不会起作用。)

到目前为止,所看到的只是如何以相反的顺序遍历字符串的字符。但是,如何使用reverse()函数使用这种方法创建Python字符串的反向副本呢?

看以下例子

>>> ''.join(reversed('TURBO'))
'OBRUT'

此代码段使用该.join()方法将反向迭代产生的所有字符合并到一个新字符串中。

当然,还可以再次将此代码写到单独的函数中创建适当的“反向字符串”。例如:

defreverse_string2(s):
    """Return a reversed copyof `s`"""
    return"".join(reversed(s))
>>>reverse_string2('TURBO')
'OBRUT'

它可以清楚地表达正在发生事情的过程,即使是小白也可以直观地了解到正在执行的过程。

第三种:移植到Python的“经典”就地字符串反转算法

这是移植到Python的“经典”就地字符串反转算法。因为Python字符串是不可变的,所以首先需要将输入字符串转换为可变的字符列表,就可以执行就地字符交换:

defreverse_string3(s):
    """Return a reversed copyof `s`"""
    chars=list(s)
    foriinrange(len(s)//2):
        tmp=chars[i]
        chars[i]=chars[len(s)-i-1]
        chars[len(s)-i-1]=tmp
    return''.join(chars)
 
>>>reverse_string3('TURBO')
'OBRUT'

但是,此方法方非常不实用,它没有发挥Python的优势,并且基本上是C算法的直接移植。哈哈哈,估计大家都不考虑吧

接下来我将对这三种实现进行基准测试。

性能比较

在实现了字符串反转方法之后,我们测试下是三种方法的性能如何

因此,我们开始进行一些基准测试:

>>>importtimeit
>>>s='abcdefghijklmnopqrstuvwxyz'*10
 
>>>timeit.repeat(lambda:reverse_string1(s))
[0.6848115339962533,0.7366074129968183,0.7358982900041156]
 
>>>timeit.repeat(lambda:reverse_string2(s))
[5.514941683999496,5.339547180992668,5.319950777004124]
 
>>>timeit.repeat(lambda:reverse_string3(s))
[48.74324739299482,48.637329410004895,49.223478018000606]

在这里插入图片描述
总结:

如果您想知道在Python中反转字符串的最佳方法是什么,我的答案是:“取决于情况”。就我个人而言,我喜欢这种reversed()方法,因为它是“自我记录”且相当快。

但是,有一种观点认为,出于性能考虑,应使用快八倍的切片方法……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值