使用collections.OrderedDict是不好的做法吗?

时间:2013-06-30 18:26:00

标签: python

当我需要一个关联数组时,我喜欢使用collections.OrderedDict,其中应该保留键的顺序。我所拥有的最好的例子是解析或创建csv文件,其中将列的顺序隐式保留在对象中是有用的。

但是我担心这是不好的做法,因为在我看来,关联数组的整个概念是键的顺序应该从不重要,并且任何操作都是依赖于排序应该只使用列表,因为这就是列表存在的原因(这可以在上面的csv示例中完成)。我没有关于此的数据,但我愿意打赌,列表的性能普遍优于OrderedDict。

所以我的问题是:OrderedDict有没有真正引人注目的用例? csv用例是一个很好的例子,说明应该使用它的地方还是坏的?

5 个答案:

答案 0 :(得分:6)

  

但是我担心这是不好的做法,因为在我看来,关联数组的整个概念是键的顺序永远不会重要,

无意义。这不是“关联数组的整个概念”。只是订单很少很重要,所以我们默认放弃订单以获得概念上更简单(更有效)的数据结构。

  

并且任何依赖于排序的操作都应该只使用列表,因为这就是列表存在的原因

在那里停下来!想一想。 如何使用列表?作为(键,值)对的列表,使用唯一键,对吧?好吧祝贺,我的朋友,你刚刚重新发明了OrderedDict,只是用了一个糟糕的API而且非常慢。对有序映射的任何概念性异议也适用于此临时数据结构。幸运的是,这些反对意见是无稽之谈。有序映射非常精细,它们与无序映射完全不同。通过良好的API和良好的性能为其提供具有恰当名称的专用实现,可以改善人们的代码。

除此之外:列表只是一种有序数据结构。虽然它们有点普遍,但几乎所有数据结构都可以用于某些列表组合(如果你向后弯曲),这并不意味着你应该总是使用列表。

  

我没有关于此的数据,但我愿意打赌,列表的性能普遍优于OrderedDict。

数据(结构)没有(不)具有性能。对数据(结构)的操作有。因此,它取决于您感兴趣的操作。如果您只需要一对列表,列表显然是正确的,迭代它或索引它是非常有效的。但是,如果你想要一个也被排序的映射,或者甚至是一小部分映射功能(例如处理重复键),那么单独一个列表是非常糟糕的,正如我上面已经解释的那样。

答案 1 :(得分:2)

对于您的特定用例(编写csv文件),不需要有序的字典。相反,请使用DictWriter

当我需要一些LIFO / FIFO访问时,我个人使用OrderedDict,因为它甚至有一个popitem方法。老实说,我想不出一个好用例,但PEP-0327提到的属性顺序是一个很好的用例:

  

XML / HTML处理库目前删除了它的顺序   属性,使用列表而不是进行过滤的字典   繁琐,或实施自己的有序词典。这影响了   ElementTree,html5lib,Genshi和更多的库。

如果您曾质疑为什么Python中存在某些功能,那么PEP是一个很好的起点,因为这是导致包含该功能的理由的详细信息。

答案 2 :(得分:0)

可能评论就足够了......

我认为如果你在不需要它的地方使用它会有问题(顺序是无关紧要的,普通的dict就足够了)。否则,代码可能比使用列表更简单。

这对任何语言构造/库都有效 - 如果它使代码更简单,则使用更高级别的抽象/实现。

答案 3 :(得分:0)

只要您对这种数据结构感到满意,并且它符合您的需求,为什么要关心?也许它不是更有效的(在速度等方面),但是,如果它存在,显然是因为它在某些情况下是有用的(或者没有人会想到写它)。

你基本上可以在Python中使用三种类型的关联数组:

  1. 经典哈希表(根本没有订单)
  2. OrderedDict(反映对象创建方式的顺序)
  3. 和二进制树 - 这不在标准的lib中 - 按照自定义顺序(不一定是按字母顺序排列)按顺序排列其键。
  4. 因此,实际上,键的顺序可以很重要。只需选择您认为更适合完成工作的结构。

答案 4 :(得分:-1)

对于CSV和类似的重复键构造,请使用namedtuple。这两个世界都是最好的。