前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我们来看看三种Python反转字符串方法的性能差距

我们来看看三种Python反转字符串方法的性能差距

作者头像
Python知识大全
发布2020-02-13 16:05:51
1.9K0
发布2020-02-13 16:05:51
举报
文章被收录于专栏:Python 知识大全

阅读本文需要5.2分钟

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

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

代码语言:javascript
复制
#你有这个:
'TURBO'

#而您想要的是
'OBRUT'

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

代码语言:javascript
复制
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时所呈现的那样,以下方法将会报错

代码语言:javascript
复制
>>> '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字符串是序列,所以这是获取字符串的反向副本的快速简便的方法:

代码语言:javascript
复制
>>>  'TURBO' [:: - 1 ]
'OBRUT'

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

代码语言:javascript
复制
defreverse_string1(s):
    """Return a reversed copyof `s`"""
    returns[::-1]
 
>>>reverse_string1('TURBO')
'OBRUT'

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

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

继续…

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

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

代码语言:javascript
复制
>>>foreleminreversed('TURBO'):
...     print(elem)
O
B
R
U
T

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

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

看以下例子

代码语言:javascript
复制
>>> ''.join(reversed('TURBO'))
'OBRUT'

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

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

代码语言:javascript
复制
defreverse_string2(s):
    """Return a reversed copyof `s`"""
    return"".join(reversed(s))
>>>reverse_string2('TURBO')
'OBRUT'

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

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

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

代码语言:javascript
复制
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算法的直接移植。哈哈哈,估计大家都不考虑吧

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

性能比较

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

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

代码语言:javascript
复制
>>>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]

汇总成表格形式:

算法

执行时间处理时间

慢一点

切片

0.72秒

1倍

反向+加入

5.39秒

7.5倍

经典

48.87秒

67.9倍

由此可见,这三种实现之间存在巨大的性能差距

切片是最快的方法,reversed()比切片慢8倍,而“经典”就地算法在该基准测试中要慢71倍!


总结:

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python 知识大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档