我有一个字典,我以特定的顺序声明,并希望一直保持这个顺序。键/值不能根据它们的值来排列顺序,我只想让它按照我声明它的顺序排列。
如果我有字典
d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}
如果我查看或遍历它,它就不是这个顺序了。是否有任何方法确保Python将保持我声明键/值的显式顺序?
我有一个字典,我以特定的顺序声明,并希望一直保持这个顺序。键/值不能根据它们的值来排列顺序,我只想让它按照我声明它的顺序排列。
如果我有字典
d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}
如果我查看或遍历它,它就不是这个顺序了。是否有任何方法确保Python将保持我声明键/值的显式顺序?
当前回答
我将给出一个简单的例子,而不是解释理论部分。
>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}
其他回答
另一种替代方法是使用Pandas数据框架,因为它保证了类字典结构中条目的顺序和索引位置。
字典会使用一个让搜索更有效率的顺序,这是你无法改变的,
您可以只使用对象列表(在简单情况下是2元素元组,甚至是类),并将项附加到末尾。然后,您可以使用线性搜索在其中查找项目。
或者,您可以创建或使用为维护秩序而创建的不同数据结构。
一般来说,你可以设计一个行为类似于字典的类,主要实现方法__contains__, __getitem__, __delitem__, __setitem__等等。这个类可以有任何你喜欢的行为,例如在键上提供一个排序的迭代器……
从Python 3.6开始,标准字典类型默认保持插入顺序。
定义
d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}
将生成一个字典,其中键按源代码中列出的顺序排列。
这是通过为稀疏哈希表使用一个简单的整数数组来实现的,其中这些整数索引到另一个数组中,该数组存储键-值对(加上计算的哈希)。后一个数组恰好按插入顺序存储项,整个组合实际上比Python 3.5及以前版本中使用的实现使用更少的内存。详见Raymond Hettinger的原创文章。
在3.6中,这仍然被认为是一个实现细节;请参阅Python 3.6新增功能文档:
The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).
Python 3.7将这个实现细节提升到一种语言规范,因此dict现在必须在所有与该版本或更新版本兼容的Python实现中保持顺序。请参阅BDFL的公告。从Python 3.8开始,字典也支持反向迭代。
在某些情况下,您可能仍然希望使用collections.OrderedDict()类,因为它在标准dict类型之上提供了一些额外的功能。比如是可逆的(这扩展到视图对象),并支持重新排序(通过move_to_end()方法)。
在开发Django项目时,我也遇到过类似的问题。我不能使用OrderedDict,因为我运行的是旧版本的python,所以解决方案是使用Django的SortedDict类:
https://code.djangoproject.com/wiki/SortedDict
例如,
from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3
注:这个答案最初来自2011年。如果你可以访问Python 2.7或更高版本,那么你应该可以访问现在的标准集合。OrderedDict,在这个帖子中其他人已经提供了许多例子。