标准库中的有序字典不提供该功能。即使库在 collections.OrderedDict 之前已经存在了几年,它具有此功能(并且本质上提供了 OrderedDict 的超集):voidspace odict 和 ruamel.ordereddict(我是后一个包的作者,它是 odict 在C):
from odict import OrderedDict as odict
p = odict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
print p[1:3]
在 ruamel.ordereddict 中,您可以放宽有序的输入要求(AFAIK,如果它的键是有序的,您不能询问 dict 的导数(对于识别 collection.OrderedDicts 的 ruamel.ordereddict 来说是很好的补充)):
from ruamel.ordereddict import ordereddict
q = ordereddict(o, relax=True)
print q[1:3]
r = odict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
print r[1:3]
如果您想(或必须)留在标准库中,您可以将collections.OrderedDict 的__getitem__ 子类化:
class SlicableOrderedDict(OrderedDict):
def __getitem__(self, k):
if not isinstance(k, slice):
return OrderedDict.__getitem__(self, k)
x = SlicableOrderedDict()
for idx, key in enumerate(self.keys()):
if k.start <= idx < k.stop:
x[key] = self[key]
return x
s = SlicableOrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
print s[1:3]
当然,您可以使用 Martijn 或 Jimmy 的较短版本来获取需要返回的实际切片:
from itertools import islice
class SlicableOrderedDict(OrderedDict):
def __getitem__(self, k):
if not isinstance(k, slice):
return OrderedDict.__getitem__(self, k)
return SlicableOrderedDict(islice(self.viewitems(), k.start, k.stop))
t = SlicableOrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
print t[1:3]
或者如果你只是想在没有子类化的情况下让所有现有的OrderedDicts 变得更聪明:
def get_item(self, k):
if not isinstance(k, slice):
return OrderedDict._old__getitem__(self, k)
return OrderedDict(islice(self.viewitems(), k.start, k.stop))
OrderedDict._old__getitem__ = OrderedDict.__getitem__
OrderedDict.__getitem__ = get_item
u = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
print u[1:3]