65

是否可以按照插入的顺序从 Python 字典中检索项目?

4

11 回答 11

67

dict如果您使用 CPython 3.6+(或 Python 3.7+ 用于 Python 的任何其他实现),标准 Python默认会执行此操作。

在旧版本的 Python 上,您可以使用collections.OrderedDict.

于 2008-09-13T20:48:36.003 回答
19

使用 OrderedDict(),从 2.7 版开始可用

只是一个好奇的问题:

from collections import OrderedDict
a = {}
b = OrderedDict()
c = OrderedDict()

a['key1'] = 'value1'
a['key2'] = 'value2'

b['key1'] = 'value1'
b['key2'] = 'value2'

c['key2'] = 'value2'
c['key1'] = 'value1'

print a == b  # True
print a == c  # True
print b == c  # False
于 2014-10-29T17:42:25.693 回答
18

从 Python 3.7 开始,标准 dict 保留插入顺序。从文档

在 3.7 版更改: 字典顺序保证为插入顺序。这种行为是 CPython 3.6 的实现细节。

因此,您应该能够正常迭代字典或使用popitem().

于 2018-08-10T00:53:46.290 回答
17

其他答案是正确的;这是不可能的,但你可以自己写。但是,如果您不确定如何实际实现这样的东西,这里有一个完整且有效的实现,它继承了我刚刚编写和测试的 dict 的子类。(请注意,传递给构造函数的值的顺序是未定义的,但会在稍后传递的值之前出现,并且您始终可以不允许使用值初始化有序 dicts。)

class ordered_dict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self._order = self.keys()

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        if key in self._order:
            self._order.remove(key)
        self._order.append(key)

    def __delitem__(self, key):
        dict.__delitem__(self, key)
        self._order.remove(key)

    def order(self):
        return self._order[:]

    def ordered_items(self):
        return [(key,self[key]) for key in self._order]


od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order()            # prints ['hello', 'goodbye']

del od["hello"]
od["monty"] = "python"
print od.order()            # prints ['goodbye', 'monty']

od["hello"] = "kitty"
print od.order()            # prints ['goodbye', 'monty', 'hello']

print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]
于 2008-09-14T00:58:30.413 回答
5

你不能用基本的 dict 类来做到这一点——它是按哈希排序的。您可以构建自己的字典,它实际上是键、值对或类似的列表,它们将被排序。

于 2008-09-13T20:39:58.803 回答
5

或者,只需使用 time.now() 作为元组中的第一个字段将键设为元组。

然后你可以用 dictname.keys() 检索键,排序,瞧!

格里

于 2008-09-15T19:31:43.350 回答
3

我以前使用过 StableDict 并取得了很好的成功。

http://pypi.python.org/pypi/StableDict/0.2

于 2008-09-15T18:15:46.853 回答
1

或者使用此处描述的PEP-372的任何实现,例如pythonutils中的odict模块

我成功使用了 pocoo.org 实现,就像替换你的一样简单

my_dict={}
my_dict["foo"]="bar"

my_dict=odict.odict()
my_dict["foo"]="bar"

并且只需要这个文件

于 2009-03-18T19:42:29.707 回答
0

除非您将密钥存储在单独的列表中以供以后参考,否则这是不可能的。

于 2008-09-19T15:56:35.460 回答
-1

如果您不需要 dict 功能,而只需要按照插入的顺序返回元组,队列不是更好吗?

于 2008-09-15T16:07:04.213 回答
-1

您可以做的是使用代表输入顺序的键插入值,然后调用sorted()项目。

>>> obj = {}
>>> obj[1] = 'Bob'
>>> obj[2] = 'Sally'
>>> obj[3] = 'Joe'
>>> for k, v in sorted(obj.items()):
...     print v
... 
Bob
Sally
Joe
>>> 
于 2014-06-04T02:50:06.983 回答