natevw natevw - 1 year ago 84
Python Question

Will a Python dict literal be evaluated in the order it is written?

Let's say that I've got a situation like this in 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)

I know that the order of
is undefined, but what I'm wondering is whether the initialization via a literal like this is guaranteed to happen in a particular order. Will the value of
always be
as asserted?

Answer Source

Dictionary evaluation order should be the same as written, but there is a outstanding bug where values are evaluated before the keys. (The bug was finally fixed in Python 3.5).

Quoting from the reference documentation:

Python evaluates expressions from left to right.

and from the bug report:

Running the following code shows "2 1 4 3", but in reference manual the evaluation order described as {expr1: expr2, expr3: expr4}

def f(i):
    print i
    return i

{f(1):f(2), f(3):f(4)}

and Guido stated:

I am sticking with my opinion from before: the code should be fixed. It doesn't look like assignment to me.

This bug is yet to be fixed, on Python 3.4 the values are still evaluated before the keys:

>>> 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)}
{1: 2, 3: 4}

Since your code doesn't require the keys to be evaluated first, your code is guaranteed to work correctly; key-value pairs are still evaluated in order even if the keys are evaluated after each corresponding value.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download