1

我在 Python 中有以下语句,其中 ori 是一个字符串

[ori[ori.rfind('') + 1:], ori[:ori.rfind('')]]

我们可以看到 ori.rfind(' ') 被调用了两次,解释器是否足够聪明,只评估函数一次?

我们可以做到以下几点:

    s = ori.rfind(' ')
    返回 [ori[s+1:], ori[:s]]

但这使用了两条线。我打算在对字符串列表的列表理解中使用这个语句,并希望这个函数是一行。

在这种情况下,解释器实际上更容易弄清楚,因为字符串是不可变的。我的猜测可能是解释器可以聪明地避免重新评估。一般来说,如果对象是不可变的,解释器是否足够聪明?

4

2 回答 2

5

我认为你不能指望解释器只评估一次函数,但是这里有一个等效的替代你当前代码的替代方法,它更短,效率与两行方法相似:

ori.rsplit(' ', 1)[::-1]

示例和时序比较:

In [1]: ori = 'foo bar baz'

In [2]: [ori[ori.rfind(' ') + 1:], ori[:ori.rfind(' ')]]
Out[2]: ['baz', 'foo bar']

In [3]: ori.rsplit(' ', 1)[::-1]
Out[3]: ['baz', 'foo bar']

In [4]: %timeit [ori[ori.rfind(' ') + 1:], ori[:ori.rfind(' ')]]
1000000 loops, best of 3: 732 ns per loop

In [5]: %timeit ori.rsplit(' ', 1)[::-1]
1000000 loops, best of 3: 514 ns per loop

In [6]: %timeit s = ori.rfind(' '); [ori[s+1:], ori[:s]]
1000000 loops, best of 3: 490 ns per loop
于 2013-03-15T17:31:27.907 回答
2

解释器可以安全地执行子表达式ori.rfind(' ')一次的唯一方法是,如果它知道

  1. rFind 表达式没有执行任何突变
  2. 第一次和第二次使用之间没有表达rFind导致任何突变

如果其中任何一个不正确,那么缓存结果和重用将是不安全的。鉴于 Python 的动态特性,几乎不可能有这些保证,因此这样的操作不能被缓存+重用

于 2013-03-15T17:34:54.950 回答