Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
664 views
in Technique[技术] by (71.8m points)

dictionary - 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 my_dict.keys() 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 my_dict['key1'] always be 1.0 as asserted?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 http://docs.python.org/reference/expressions.html#expression-lists 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 fixed in Python 3.5, so on Python 3.4 and earlier 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)}
2
1
4
3
{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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...