Python 3.6 和 Python 3.5 中字典顺序的区别

Differences between Dictionary orders in Python 3.6 and Python 3.5

我正在尝试了解 python 3.6.7python 3.5.2 中的 python 词典之间的区别。他们存储键值对顺序的方式似乎不同。

例如,假设有一个名为 di:

的字典
    di = {'a':1,'A':1,'b':2, 'B':2, 'c':3, 'C':3}

Python 3.5.2中,当我打印di时,输出是:

    {'C': 3, 'a': 1, 'A': 1, 'B': 2, 'c': 3, 'b': 2}

然而,在Python 3.6.7中是:

    {'a': 1, 'A': 1, 'b': 2, 'B': 2, 'c': 3, 'C': 3}

两个版本之间有什么变化? 我怎样才能使我的代码排序 python 3.6.7 类似于 3.5.2 的结果。

P.S。我知道在 Python 字典中实际上 no order。这里的 order 一词是为了让 reader 更容易理解我的问题。 谢谢。

字典的顺序是"allowed"每个程序运行都不一样,更不用说版本了。事实上,它在每个版本上都是一致的,只有 CPython 知道的 实现细节 *。您的程序不应依赖此行为。

How can I make my code order the result of python 3.6.7 similar to 3.5.2's.

使用 OrderedDict!

* 实际上,as of Python 3.7,insertion-order 的保留正式成为语言规范的一部分。

TLDR:

要复制 hash-based 排序,您必须采用明确排序 dict 并强加您自己的排序。

from collections import OrderedDict

def cpy35dict(source_dict):
    """Apply hash-ordering to a dictionary"""
    return OrderedDict(  # ensure stable ordering
        sorted(          # order items by key hash
            source_dict.items(),
            key=lambda item: hash(item[0])
        )
    )

这复制了 CPython 到 Python 3.5 中使用的顺序。 请注意,Python 语言规范对 Python 3.7 之前的订单做出 保证 - 如果您还应该在 Python 3.5 和之前使用它坚持顺序。


dict类容器基本上有三种订单类型:

  • 无顺序: 项目没有特定顺序。每次访问可能 return 不同的顺序。
  • 具体订单: 商品有well-defined订单。每次访问 return 都是相同的顺序。
  • 任意顺序: 顺序未定义。它可能使用也可能不使用特定顺序。

根据 Python 规范,dict 任意顺序 到 Python 3.6 和 插入顺序 因为 Python 3.7.

Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6. [Mapping Types — dict¶]

但是,任意顺序不排除特定顺序。它基本上意味着 "whatever the implementation feels like"。不同的实现使用不同的方案来实现dict.

  • PyPy 使用插入顺序,因为 Python 2.7/3.2

  • CPython 3.5- 使用底层哈希函数的排序。由于几种类型具有加盐哈希,这意味着您在每次调用时获得不同的顺序。

  • CPython 3.6 使用插入项目的顺序。这是明确的实现细节。

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon [What's new in Python 3.6]

换句话说,Python 3.6 及更早版本的代码应该 假设dict 的顺序。只有 Python 3.7 及更高版本的代码应该对 dict.

的排序做出假设