首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python -具有多个(目标列表"=")组的赋值语句是否有优势/劣势?

Python -具有多个(目标列表"=")组的赋值语句是否有优势/劣势?
EN

Stack Overflow用户
提问于 2013-02-28 05:57:47
回答 2查看 660关注 0票数 1

here找到的递归字典的解决方案中,我看到了以下Python食谱:

代码语言:javascript
复制
class RecursiveDict(dict):
    """Implementation of perl's autovivification feature."""
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

关于value = self[key] = type(self)()这一行:与下面的代码相比,它有什么优点或缺点?或者仅仅是语法问题?

代码语言:javascript
复制
self[key] = type(self)()
value = self[key]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-28 06:04:02

它主要是语法糖,但不是针对您列出的语句;相反,它等同于

代码语言:javascript
复制
value = type(self)()
self[key] = value

要查看差异,请在Python提示符下键入以下内容:

代码语言:javascript
复制
>>> class FakeDict(object):
...  def __setitem__(self, k, v):
...   pass
...  def __getitem__(self, k):
...   raise KeyError("boom!")
... 
>>> d = FakeDict()
>>> x = d[1] = 42
>>> d[1] = 42
>>> x = d[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __getitem__
KeyError: boom!

当然,对于行为良好的dict,这并不重要,但是

代码语言:javascript
复制
self[key] = type(self)()
value = self[key]

不会在第二行执行多余的dict查找,因此在循环中,速记可能会带来性能优势。

在一般的情况下,,它甚至比我上面所说的还要复杂一点。速记赋值实际上等同于

代码语言:javascript
复制
__some_temporary = type(self)()
value = __some_temporary
self[key] = __some_temporary

只有因为value是一个简单的局部变量,才会出现简化形式的value = type(self)(); self[key] = value。如果将value替换为可能失败的container[key]形式的表达式,等价性将不再有效。

票数 4
EN

Stack Overflow用户

发布于 2013-02-28 06:01:08

它只是一个语法。有时它会使代码更容易阅读,有时却不会。

但是会发生什么呢?另一个答案让我感到好奇:我对它进行了评论,说compier可能使用了“寄存器或变量”,而这正是发生的事情。让我们反编译一个简单的函数:

代码语言:javascript
复制
>>> import dis
>>> def f():
...     a = b = c = 1
...     return a
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              3 DUP_TOP             
              4 STORE_FAST               0 (a)
              7 DUP_TOP             
              8 STORE_FAST               1 (b)
             11 STORE_FAST               2 (c)

  3          14 LOAD_FAST                0 (a)
             17 RETURN_VALUE        

最右边的值(在我的例子中是type(self)() )被加载到堆栈(考虑“局部变量”),然后复制到堆栈(在基于堆栈的VM操作中消耗堆栈,所以如果你想“保留”一个值,你需要制作多个副本),然后赋值,然后复制,然后赋值,依此类推。也就是说,转换回Python。这类似于:

代码语言:javascript
复制
def f():
    t = 1
    a = t
    b = t
    c = t
    return a

编译器甚至保留了赋值从左到右的顺序(a,b,c)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15123267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档