繁体   English   中英

简化语句'。'。join(string.split('。')[0:3])

[英]Simplify statement '.'.join( string.split('.')[0:3] )

我习惯于用C / C ++编写代码,当我看到以下数组操作时,我感到有些CPU浪费了:

version = '1.2.3.4.5-RC4'                 # the end can vary a lot
api = '.'.join( version.split('.')[0:3] ) # extract '1.2.3'

因此,我想知道:

  • 将这一行执行(解释)为创建临时数组(内存分配),然后连接前三个单元(再次分配内存)吗?
    还是python解释器足够聪明?
    (我也对PythranParakeetNumbaCython和其他python解释器/编译器在这种情况下所做的优化感到好奇。)

  • 是否有技巧来编写替换行,以提高CPU效率,并且仍然可以理解/优雅?
    (您可以提供特定的Python2和/或Python3技巧和提示)

我不知道为此使用CPU的情况,但这不是为什么我们以某种方式使用高级语言吗?

另一种解决方案是使用正则表达式,使用编译模式应允许进行背景优化:

import re
version = '1.2.3.4.5-RC4'
pat = re.compile('^(\d+\.\d+\.\d+)')
res = re.match(version)
if res:
  print res.group(1)

编辑:根据建议@jonrsharpe,我也运行了timeit基准测试。 这是我的结果:

def extract_vers(str):
   res = pat.match(str)
   if res:
     return res.group(1)
   else:
     return False

>>> timeit.timeit("api1(s)", setup="from __main__ import extract_vers,api1,api2; s='1.2.3.4.5-RC4'")
1.9013631343841553
>>> timeit.timeit("api2(s)", setup="from __main__ import extract_vers,api1,api2; s='1.2.3.4.5-RC4'")
1.3482811450958252
>>> timeit.timeit("extract_vers(s)", setup="from __main__ import extract_vers,api1,api2; s='1.2.3.4.5-RC4'")
1.174590826034546

编辑:但是无论如何,Python中存在一些库,例如distutils.version可以完成这项工作。 你应该看看那个答案

要回答您的第一个问题:不,这将不会由口译员进行优化。 Python将根据字符串创建一个列表,然后为切片创建第二个列表,然后将列表项放回一个新的字符串中。

为了覆盖第二个,您可以通过使用可选的maxsplit参数限制split稍微优化此设置:

>>> v = '1.2.3.4.5-RC4'
>>> v.split(".", 3)
['1', '2', '3', '4.5-RC4']

一旦第三个'.' 找到后,Python停止搜索字符串。 您也可以通过删除切片的默认0参数来稍微修饰一下:

api = '.'.join(version.split('.', 3)[:3])

但是请注意,性能上的任何差异都可以忽略不计:

>>> import timeit
>>> def test1(version):
    return '.'.join(version.split('.')[0:3])

>>> def test2(version):
    return '.'.join(version.split('.', 3)[:3])

>>> timeit.timeit("test1(s)", setup="from __main__ import test1, test2; s = '1.2.3.4.5-RC4'")
1.0458565345561743
>>> timeit.timeit("test2(s)", setup="from __main__ import test1, test2; s = '1.2.3.4.5-RC4'")
1.0842980287537776

较长的字符串包含更多不相关的'.'maxsplit的好处变得更加明显'.' S:

>>> timeit.timeit("s.split('.')", setup="s='1.'*100")
3.460900054011617
>>> timeit.timeit("s.split('.', 3)", setup="s='1.'*100")
0.5287887450379003

我习惯于用C / C ++编写代码,当我看到以下数组操作时,我感到有些CPU浪费了:

对于面临Python代码的C / C ++程序员来说,CPU浪费感觉绝对是正常的。 您的代码:

version = '1.2.3.4.5-RC4'                 # the end can vary a lot
api = '.'.join(version.split('.')[0:3])   # extract '1.2.3'

在python中绝对可以没有简化的可能 必须执行1000次后,才考虑使用库函数编写自己的 函数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM