0

我有以下代码:

from functions import *

powers = AutoVivification()
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}

print powers[1]

我的自动生存如下(取自:实现嵌套字典的最佳方法是什么?):

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

它打印以下内容:

{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1}

请注意顺序已更改。现在是按字母顺序排列的。有什么办法可以防止这种情况发生吗?抱歉,不够清楚:(不更改键,并使用“使任意扩展字典变得超级容易”的 autovivificaion 属性)

4

3 回答 3

3

正如文档所说:

键和值以非随机的任意顺序迭代,随 Python 实现而变化,并取决于字典的插入和删除历史。

换句话说,字典没有内在的顺序。你可以看到,没有所有复杂的附加功能:

>>> print {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}
{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1}

如果您想要一个按插入顺序维护其键的字典,您可以使用OrderedDict.


但是,在这种情况下,这还不足以帮助您。如果您构造 a dict(具有任意顺序),然​​后将其传递给 a OrderedDict,您所做的就是冻结该初始任意顺序:

>>> from collections import OrderedDict
>>> print OrderedDict({'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1})
OrderedDict([('A', 1), ('c1', 0.5), ('gamma', 1), ('lambda', 1)])

其中repr应该OrderedDict给你一个线索,告诉你如何创建一个OrderedDict带有初始值的顺序:从一个序列创建它,其中每个元素都是一个键值对:

>>> print OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)])
OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)])

如果您想自动激活OrderedDict,您可以通过在现有课程中使用OrderedDict而不是来做到这一点。dict但是,您可能需要考虑您正在使用的类的一些问题。特别是,您确实希望super对父类方法使用而不是经典风格的调用;如果你这样做了,你可以定义class AutoVivifiedOrderedDict(OrderedDict, AutoVivification): pass并完成它!另外,我认为您的班级不会按原样正确腌制。


如果您使用 adefaultdict进行自动生存,它已经处理了所有棘手的问题:

def AutoVivification():
    return defaultdict(AutoVivification)

如果你想添加排序,你需要一个OrderedDefaultDict,所以你可以这样做:

def OrderedAutoVivification():
    return OrderedDefaultDict(AutoVivification)

如果您不知道如何创建OrderedDefaultDict自己,请搜索食谱。(您几乎可以从两个类继承......除了它们具有不同的签名这一事实,因此您需要考虑您__init__应该是什么样子并使用正确的参数显式调用正确的基本初始化程序。有关一些讨论,请参阅此问题。 )

于 2013-12-12T19:54:54.907 回答
-1

字典在 Python 中没有排序。排序后将不会保留其顺序。相反,使用

from collections import OrderedDict

powers = OrderedDict()
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}

print powers[1]
于 2013-12-12T19:36:26.647 回答
-4

您可以添加另一个键来指定顺序...

import operator

powers = {0: ['c1', 0.5], 1: ['gamma', 1], 2: ['lambda', 1], 3: ['A', 1]}
print sorted(powers.items(), key=operator.itemgetter(0))

希望这可以帮助!

于 2013-12-12T19:36:40.493 回答