【问题标题】:how to print dictionary as defined [duplicate]如何按定义打印字典[重复]
【发布时间】:2013-12-12 19:31:09
【问题描述】:

我有以下代码:

from functions import *

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

print powers[1]

我的自动复活如下(取自:What is the best way to implement nested dictionaries?):

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 属性)

【问题讨论】:

  • 字典是哈希图,没有排序。如果您需要订购,可以使用集合中的OrderedDict
  • 另外,您当前的AutoVivification 类本质上是一个嵌套的defaultdict,如dd = lambda: defaultdict(dd)...
  • 所有关于自动复活的东西都与问题无关。只需执行print {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1},您就会看到以完全相同的方式重新排序的值。
  • 这意味着这是关于 SO 的大约 300 个其他问题的重复……我将随机选择其中一个。
  • @abarnert 不是最佳选择,因为接受的答案使用 django SortedDicts (虽然第二个答案使用 OrderedDict)......但无论如何,这个问题已经得到了详尽的回答。跨度>

标签: python dictionary autovivification


【解决方案1】:

正如the documentation 所说:

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

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

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

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


但是,在这种情况下,这还不足以帮助您。如果您构造一个dict(具有任意顺序),然​​后将其传递给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)])

OrderedDict 中的 repr 应该为您提供如何创建具有初始值顺序的 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 并完成它!另外,我认为您的课程不会按原样正确腌制。


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

def AutoVivification():
    return defaultdict(AutoVivification)

如果您想添加订单,您需要OrderedDefaultDict,所以您可以这样做:

def OrderedAutoVivification():
    return OrderedDefaultDict(AutoVivification)

如果您不知道如何自己创建OrderedDefaultDict,请搜索食谱。 (您几乎可以只从这两个类继承......除了它们具有不同的签名这一事实,因此您需要考虑您的 __init__ 应该是什么样子,并使用正确的论点。请参阅this question 进行一些讨论。)

【讨论】:

  • 试过了,还是一样。将我的代码更改为:powers = OrderedAutoVivification(),使用您的代码:def OrderedAutoVivification(): return OrderedDefaultDict(AutoVivification),并使用来自linkOrderedDefaultDict。我会继续寻找..
  • 我也许应该用新代码提交另一个问题。嗯。我的结论是这并不简单..(显然?)
  • @juggler:你读过我的全部答案了吗?我解释了为什么你会得到完全相同的东西:{'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}dict,这意味着它具有任意顺序。将任意顺序的dict 分配给powers[1] 只会将原始任意顺序锁定为永久顺序。首先,您需要避免构造 dict,方法是使用一系列对(或逐个添加值,或以其他方式)。
  • 我确实阅读了整本书。没完全理解 :-) 我确实逐渐弄清楚(也尝试了其他人的许多建议)......基本上,我的目标不是同时调用自动激活和有序字典。现在,这完全是另一个问题,您很可能已经回答了。我上面的代码实际上试图做的是创建一个字典字典,它是我要打印的子字典。所以这段代码有效:powers = AutoVivification() powers[1] = OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)])。 :-)
  • @juggler:是的,这会满足你的需求。
【解决方案2】:

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

from collections import OrderedDict

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

print powers[1]

【讨论】:

  • 这里对“可排序”的引用令人困惑;我不确定你的意思。
  • 使用OrderedDict()会和AutoVivification()有同样的效果,还有ordered呢? (我对 autovivification 仍然很模糊。我真正知道的是,它使任意扩展字典变得超级容易,这很棒)
  • @MichaelJensen:正如 l4mpi 的评论所解释的那样,使用 defaultdict 进行自动激活的简单方法。如果您希望它订购自动激活,您可以使用OrderedDefaultDict(如果您不知道如何自己构建它,请搜索它的配方)完全相同的方式。跨度>
  • @abarnert 我澄清了我的答案,谢谢。我也不知道 AutoVivification() 是什么! :)
  • 好的,既然我知道你所说的“排序”是什么意思,我看不出它是如何相关的。他从来没有对字典进行排序,你也不是。重要的是,即使你对它什么都不做,它也不会保留它的顺序。
【解决方案3】:

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

import operator

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

希望这会有所帮助!

【讨论】:

  • 答错问题?
  • 怎么样? DropDownListValues 是一个字典。
  • 1.这是订购 dict 和 2 的最糟糕的方式。这个问题与 jinja 或 html 无关。
  • 3.安装 jinja2 来订购字典有点无意义。
  • @Hyperboreus 我相信这只是一个示例(或快速复制粘贴现有代码) - 实际订购过程与 jinja 没有任何关系。但 IMO 这是一个糟糕的例子,因为它过于冗长、格式错误并且包含大部分不相关的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2015-02-24
相关资源
最近更新 更多