当我需要一个关联数组时,我喜欢使用collections.OrderedDict,其中应该保留键的顺序。我所拥有的最好的例子是解析或创建csv文件,其中将列的顺序隐式保留在对象中是有用的。
但是我担心这是不好的做法,因为在我看来,关联数组的整个概念是键的顺序应该从不重要,并且任何操作都是依赖于排序应该只使用列表,因为这就是列表存在的原因(这可以在上面的csv示例中完成)。我没有关于此的数据,但我愿意打赌,列表的性能普遍优于OrderedDict。
所以我的问题是:OrderedDict有没有真正引人注目的用例? csv用例是一个很好的例子,说明应该使用它的地方还是坏的?
答案 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中使用三种类型的关联数组:
OrderedDict
(反映对象创建方式的顺序)因此,实际上,键的顺序可以很重要。只需选择您认为更适合完成工作的结构。
答案 4 :(得分:-1)
对于CSV和类似的重复键构造,请使用namedtuple。这两个世界都是最好的。