backticks对python解释器意味着什么:`num`
我在玩列表理解的游戏,在另一个网站上看到了这个小片段:backticks对python解释器意味着什么:`num`,python,list-comprehension,Python,List Comprehension,我在玩列表理解的游戏,在另一个网站上看到了这个小片段: return ''.join([`num` for num in xrange(loop_count)]) 我花了几分钟尝试复制函数(通过键入),然后才意识到`num`位破坏了它 在这些字符中包含语句的作用是什么?从我看来,它相当于str(num)。但当我计时时: return ''.join([str(num) for num in xrange(10000000)]) 需要4.09秒,而: return ''.join([`num`
return ''.join([`num` for num in xrange(loop_count)])
我花了几分钟尝试复制函数(通过键入),然后才意识到`num`
位破坏了它
在这些字符中包含语句的作用是什么?从我看来,它相当于str(num)。但当我计时时:
return ''.join([str(num) for num in xrange(10000000)])
需要4.09秒,而:
return ''.join([`num` for num in xrange(10000000)])
需要2.43秒
两者给出的结果相同,但其中一个要慢得多。这是怎么回事
编辑:奇怪的是
repr()
给出的结果比`num`
稍慢。2.99秒对2.43秒。使用Python2.6(还没有尝试过3.0)。Backticks是repr()
不推荐使用的别名。不要再使用它们了,Python 3.0中删除了语法
使用backticks似乎比在2.x版中使用repr(num)
或num.\uuuu repr\uuuu()
更快。我猜这是因为需要在全局名称空间(对于repr
)或对象名称空间(对于\uuuu repr\uuu
)中分别进行额外的字典查找
使用
dis
模块证明了我的假设:
def f1(a):
return repr(a)
def f2(a):
return a.__repr__()
def f3(a):
return `a`
展览包括:
>>> import dis
>>> dis.dis(f1)
3 0 LOAD_GLOBAL 0 (repr)
3 LOAD_FAST 0 (a)
6 CALL_FUNCTION 1
9 RETURN_VALUE
>>> dis.dis(f2)
6 0 LOAD_FAST 0 (a)
3 LOAD_ATTR 0 (__repr__)
6 CALL_FUNCTION 0
9 RETURN_VALUE
>>> dis.dis(f3)
9 0 LOAD_FAST 0 (a)
3 UNARY_CONVERT
4 RETURN_VALUE
f1
涉及对repr
的全局查找,f2
涉及对\uuuuuu repr\uuuu
的属性查找,而backtick运算符在单独的操作码中实现。由于字典查找(LOAD\u GLOBAL
/LOAD\u ATTR
)和函数调用(CALL\u function
)都没有开销,因此回跳速度更快
我猜Python的人认为为repr()
单独使用一个低级操作是不值得的,同时使用repr()
和反勾号违反了这一原则
“应该有一种——最好只有一种——显而易见的方法”
因此,该功能在Python 3.0中被删除。我的猜测是
num
没有定义方法\uuuu str\uuu()
,因此str()
必须对\uu repr\uu>进行第二次查找
反勾号直接查找\uuu repr\uu
。如果这是真的,那么使用repr()
而不是反勾号应该会得到相同的结果。反勾号引用通常是无用的,在Python 3中已经消失了
值得一提的是:
''.join(map(repr, xrange(10000000)))
对我来说,比backtick版本稍微快一点。但担心这一点可能是过早的优化。我想知道,如何用一些函数调用替换backticks,但这似乎是不可能的,或者是真的?使用repr()而不是backticks。Backticks是repr()come 3.0的折旧语法。实际上,我更喜欢backticks的外观,而不是调用另一个函数;它可能很难输入(在某些键盘上),很难看到它是什么,很难在Python书籍中正确打印。Etc.@kaizer.se:谢谢你指出这一点。这可能是删除反勾号的主要原因,请参阅邮件列表存档中的Guidos语句:发布此消息的最初问题是因为我无法在键盘上找到反勾号;)下面的波浪线看起来是谷歌搜索后的结果。为什么要后退一步,使用map而不是列表/迭代器理解呢?事实上,timeit
为''生成更快的结果。join(map(repr,xrange(010000))
比''。join([repr(i)为xrange(010000)中的i)]
(对于''更糟糕。join((repr(i)为xrange中的i)(0,1000000))
)。这有点令人失望;-)博宾斯的结果对我来说并不奇怪。根据经验,Python中的隐式循环比显式循环快,通常快得惊人<代码>映射
是用C实现的,使用C循环,比在虚拟机中执行的Python循环快得多。这也不奇怪,这对列表理解的声誉来说太糟糕了(在本例中命中率为30%)。但我宁愿使用清晰的速度代码,而不是火爆的速度代码,除非这真的很重要,所以这里没什么大不了的。尽管如此,map()函数并没有让我觉得不清楚,LC有时被高估了。map
对我来说似乎非常清晰和简洁,我甚至不懂Python。在阅读了上的“另一个站点”后,我遇到了类似的问题,找到了这个页面。问得好,回答得好:)