我正在尝试获取一个排序的字典。但mydict
和orddict
之间的项目顺序似乎没有变化。
from collections import OrderedDict
mydict = {'a':1,'b':2,'c':3,'d':4}
orddict = OrderedDict(mydict)
print(mydict,orddict)
# print items in mydict:
print('mydict')
for k,v in mydict.items():
print(k,v)
print('ordereddict')
# print items in ordered dictionary
for k,v in orddict.items():
print(k,v)
# print the dictionary keys
# for key in mydict.keys():
# print(key)
# print the dictionary values
# for value in mydict.values():
# print(value)
答案 0 :(得分:10)
OrderedDict
保留已插入的订单元素:
>>> od = OrderedDict()
>>> od['c'] = 1
>>> od['b'] = 2
>>> od['a'] = 3
>>> od.items()
[('c', 1), ('b', 2), ('a', 3)]
>>> d = {}
>>> d['c'] = 1
>>> d['b'] = 2
>>> d['a'] = 3
>>> d.items()
[('a', 3), ('c', 1), ('b', 2)]
因此,OrderedDict
不会订购您的元素,保留您提供的订单。
如果你想“排序”字典,你可能想要
>>> sorted(d.items())
[('a', 1), ('b', 2), ('c', 3)]
答案 1 :(得分:3)
有序词典就像常规词典一样,但它们记住了项目的插入顺序。迭代有序字典时,项目按照其键首次添加的顺序返回。
所以它只按添加到字典中的顺序排序
您可以按键构建OrderedDict订单,如下所示
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[0]))
或简单地在评论中提及@ShadowRanger
orddict = OrderedDict(sorted(d.items()))
如果您想按价值订购,
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[1]))
答案 2 :(得分:3)
Brian添加答案,OrderedDict
非常棒。这就是原因:
您可以将其用作简单的dict
对象,因为它支持与collections.counter等其他Mapping
对象进行相等性测试。
OrderedDict
保留了插入顺序,如Brian所解释的那样。除此之外,它还有一个方法popitem,它以LIFO顺序返回(键,值)对。因此,您也可以将其用作映射'。
你不仅可以获得dict
的全部功能,还可以获得一些很酷的技巧。
答案 3 :(得分:1)
自Python 3.7起,一项新的改进是:
dict对象的插入顺序保留性质已声明是Python语言规范的正式组成部分。
这意味着不再需要OrderedDict。它们几乎相同。但是要注意一些差异。
from collections import OrderedDict
d = {'b': 1, 'a': 2}
od = OrderedDict([('b', 1), ('a', 2)])
# they are equal with content and order
assert d == od
assert list(d.items()) == list(od.items())
assert repr(dict(od)) == repr(d)
很明显,两个对象的字符串表示形式有所不同,dict
对象的形式更自然,更紧凑。
对于两者之间的不同方法,可以用集合论来回答这个问题:
d_set = set(dir(d))
od_set = set(dir(od))
od_set.difference(d_set)
# {'__dict__', '__reversed__', 'move_to_end'}
这意味着OrderedDict
至少具有dict
没有内置的两个功能,但是此处显示了解决方法:
# 1) OrderedDict can be reversed (but then what?)
reversed(od)
# <odict_iterator at 0x7fc03f119888>
reversed(d)
# TypeError: 'dict' object is not reversible
# better way to reverse a dict
dict(reversed(list(d.items()))) # {'a': 2, 'b': 1}
# 2) OrderedDict has 'move_to_end' method
od.move_to_end('b') # now it is: OrderedDict([('a', 2), ('b', 1)])
# dict does not, but similar can be done with
d['b'] = d.pop('b') # now it is: {'a': 2, 'b': 1}
答案 4 :(得分:0)
来自the documentation for OrderedDict
(重点是我):
订购字典与常规字典一样,但有一些额外的 与订购操作有关的功能。他们变得越来越少 现在,内置
dict
类已经具备了该功能,这一点很重要 记住插入顺序(此新行为在 Python 3.7)。与
dict
的某些区别仍然存在:
常规
dict
的设计非常擅长映射 操作。跟踪插入顺序是次要的。
OrderedDict
被设计为擅长重新排序操作。 空间效率,迭代速度和更新性能 操作是次要的。从算法上讲,
OrderedDict
可以处理频繁的重新排序 操作比dict
更好。这使其适合跟踪 最近访问(例如在LRU cache中)。
OrderedDict
的相等操作将检查匹配顺序。
popitem
的{{1}}方法具有不同的 签名。它接受一个可选参数来指定要弹出的项目。
OrderedDict
具有OrderedDict
方法 有效地将元素重新定位到端点。在Python 3.8之前,
move_to_end
缺少dict
方法。