cpython 3.6 dict order in dict comprehension

时间:2017-08-04 12:38:29

标签: dictionary python-3.6 dictionary-comprehension

Since in CPython 3.6 dicts are ordered (I know it's not guaranteed - yet awesome to use), so I expected the following dict comprehension to preserve the order:

# attempt to get only specific k:v from dict jrn_blocks in order
jrn_blocks = {"header":0, "open":1, "detached":2, "rps_command":3, "close_no_save":4}
recip = "header,open,close_no_save"
{k: v for k, v in jrn_blocks.items() if k in recip}
# -> gives me: {'close_no_save': 4, 'header': 0, 'open': 1}
# -> I would expect: {'header': 0, 'open': 1, 'close_no_save': 4}

If I just use a list comprehension on item tuples, order is preserved:

[(k, v) for k, v in jrn_blocks.items() if k in recip]
# -> gives me: [('header', 0), ('open', 1), ('close_no_save', 4)]

As soon as I try to create a dictionary from these tuples, the order is lost again:

dict([(k, v) for k, v in jrn_blocks.items() if k in recip])
# -> gives me: {'close_no_save': 4, 'header': 0, 'open': 1}

Is this expected behavior?
Is there an alphabetical key sorting happening in the background?
Or is there another elegant way to do this kind of "dict filter" while preserving order?
Thank you so much in advance!

1 个答案:

答案 0 :(得分:0)

我终于找到了自己:
当我输入时,我被从REPL返回的内容所迷惑:

{k: v for k, v in jrn_blocks.items() if k in recip}
# {'close_no_save': 4, 'header': 0, 'open': 1}

但是当我将字典理解的结果存储在变量中时,我发现键是按照预期的顺序:

jd = {k: v for k, v in jrn_blocks.items() if k in recip}
print(jd.keys())
# {'header': 0, 'open': 1, 'close_no_save': 4}