Python dict文字是否会按照它编写的顺序进行评估?

nat*_*evw 15 python dictionary

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

_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)
Run Code Online (Sandbox Code Playgroud)

我知道顺序my_dict.keys()是未定义的,但我想知道的是,通过像这样的文字的初始化是否保证以特定的顺序发生.总值是否my_dict['key1']会被1.0断言?

Mar*_*ers 19

字典评估顺序应该是一样的写的,但有一个突出的缺陷,其中是在之前评估.(该错误最终在Python 3.5中修复).

引用参考文档:

Python从左到右评估表达式.

并从错误报告:

运行以下代码显示"2 1 4 3",但在参考手册 http://docs.python.org/reference/expressions.html#expression-lists中描述的评估顺序为{expr1: expr2, expr3: expr4}

def f(i):
    print i
    return i

{f(1):f(2), f(3):f(4)}
Run Code Online (Sandbox Code Playgroud)

和圭多说:

我坚持以前的意见:代码应该修复.它看起来不像我的任务.

这个错误在Python 3.5中得到修复,因此在Python 3.4及更早版本中,仍然会在键之前评估值:

>>> 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}
Run Code Online (Sandbox Code Playgroud)

由于您的代码不需要首先评估密钥,因此您的代码可以保证正常工作; 即使在每个相应值之后评估键,仍然按顺序评估键值对.


nat*_*evw 6

根据有关评估顺序Python文档,这应该有明确定义的行为:

在以下行中,表达式将按其后缀的算术顺序进行计算:

…
{expr1: expr2, expr3: expr4}
…
Run Code Online (Sandbox Code Playgroud)

因此,无论dict最终迭代的项目的顺序如何,文字字典表达式的值(和键!)将始终按照它们在我的Python源代码中出现的顺序进行评估.

  • 除了http://bugs.python.org/issue11205,它表明Python实现中存在该规则的错误. (4认同)