首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python文字是否会按照编写的顺序进行计算?

Python文字是否会按照编写的顺序进行计算?
EN

Stack Overflow用户
提问于 2015-01-26 18:49:31
回答 3查看 1.7K关注 0票数 16

假设我在Python中遇到了这样的情况:

代码语言:javascript
复制
_avg = {'total':0.0, 'count':0}    # HACK: side-effects stored here

def procedure(n):
  _avg['count'] += 1
  _avg['total'] += n
  return n

def get_average():
  return _avg['total'] / _avg['count']

my_dict = {
  'key0': procedure(0),
  'key2': procedure(2),
  'key1': get_average()
}
assert(my_dict['key1'] == 1.0)

我知道my_dict.keys()的顺序是没有定义的,但我想知道的是,通过这样的文字进行初始化是否会以特定的顺序进行。my_dict['key1']的值会像断言的那样总是1.0吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-26 18:52:12

字典计算顺序应该与编写的相同,但是有一个突出的缺陷,其中值在键之前进行求值。(这个bug最终用Python3.5修复了)。

引用参考文献的话

Python从左到右计算表达式。

从臭虫报告来看:

运行以下代码将显示"2 1 4 3",但在参考手册http://docs.python.org/reference/expressions.html#expression-lists中,计算顺序被描述为{expr1: expr2, expr3: expr4} def (I):打印i返回I {f(1):f(2),f(3):f(4)}

Guido说:

我坚持以前的观点:代码应该是固定的。在我看来不像是任务。

这个bug在Python3.5中是固定的,所以在Python3.4和更早的时候,值仍然在键之前被计算:

代码语言:javascript
复制
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=4, micro=2, releaselevel='final', serial=0)
>>> def f(i):
...     print(i)
...     return i
... 
>>> {f(1):f(2), f(3):f(4)}
2
1
4
3
{1: 2, 3: 4}

因为您的代码不需要首先计算键,所以保证代码正确工作;键-值对仍然是按顺序计算的,即使键是在每个对应值之后计算的。

票数 19
EN

Stack Overflow用户

发布于 2015-01-26 18:49:31

根据关于计算顺序的Python文档,这应该具有定义良好的行为:

在下面的行中,表达式将按后缀的算术顺序进行计算: …{expr1: expr2,expr3: expr4}…

因此,不管dict中的项的顺序如何,值(和键)最终都会被迭代。文本字典表达式的计算顺序总是与我的Python源代码中显示的顺序相同。

票数 7
EN

Stack Overflow用户

发布于 2015-03-04 23:58:05

Python3.4.2上的当前行为可以在分解后的字节码中非常清楚地看到:值是在键之前计算的,而不是从左到右。

代码语言:javascript
复制
>>> dis.dis(lambda: {f('1'): f('2'), f('3'): f('4')})
  1           0 BUILD_MAP                2
              3 LOAD_GLOBAL              0 (f)
              6 LOAD_CONST               1 ('2')
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             12 LOAD_GLOBAL              0 (f)
             15 LOAD_CONST               2 ('1')
             18 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             21 STORE_MAP
             22 LOAD_GLOBAL              0 (f)
             25 LOAD_CONST               3 ('4')
             28 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             31 LOAD_GLOBAL              0 (f)
             34 LOAD_CONST               4 ('3')
             37 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             40 STORE_MAP
             41 RETURN_VALUE

然而,这也说明了为什么这也不是那么简单的原因:STORE_MAP按这个顺序期望值和键;更改顺序需要在每对之后添加一个ROT_TWO操作码,或者需要在每对后面添加一个STORE_MAP_EX操作码;第一个操作码是性能下降,而第二个操作码意味着在处理字节码的每段代码中都要处理另一个操作码。

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

https://stackoverflow.com/questions/28156687

复制
相关文章

相似问题

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