正如其他人所提到的,在Python字典本质上是无序的。然而,在任何时候,通过使用它们的keys()
或items()
方法可获得其当前键或键值对的列表。
使用这些列表的一个潜在问题是,如果字典自上次使用以来已被修改(或突变),那么不仅它们的内容,而且它返回的顺序可能会有所不同。这意味着您通常不能存储和重用列表,除非您在每次更改字典时更新它,以防万一您需要它。
为了使这种方法更易于管理,您可以将字典和辅助列表合并到一个新的派生类中,该派生类负责处理两者之间的同步,并提供一个使用列表的当前内容的get_range()
方法。下面是示例代码,显示了如何完成此操作。它基于我从this ActiveState Python Recipe的代码中获得的想法。
class dict_with_get_range(dict):
def __init__(self, *args, **kwrds):
dict.__init__(self, *args, **kwrds)
self._list_ok = False
def _rebuild_list(self):
self._list = []
for k,v in self.iteritems():
self._list.append((k,v))
self._list_ok = True
def get_range(self, begin, end):
if not self._list_ok:
self._rebuild_list()
return dict(self._list[i] for i in range(begin,end+1))
def _wrapMutatorMethod(methodname):
_method = getattr(dict, methodname)
def wrapper(self, *args, **kwrds):
# Reset 'list OK' flag, then delegate to the real mutator method
self._list_ok = False
return _method(self, *args, **kwrds)
setattr(dict_with_get_range, methodname, wrapper)
for methodname in 'delitem setitem'.split():
_wrapMutatorMethod('__%s__' % methodname)
for methodname in 'clear update setdefault pop popitem'.split():
_wrapMutatorMethod(methodname)
del _wrapMutatorMethod # no longer needed
dct = dict_with_get_range({"a":"b", "c":"d", "e":"f"})
print dct.get_range(0, 1)
# {'a': 'b', 'c': 'd'}
del dct["c"]
print dct.get_range(0, 1)
# {'a': 'b', 'e': 'f'}
的基本思想是从dict
还具有由新get_range()
方法它提供了普通的字典对象不使用内部的内容列表派生一个新类。为了减少更新(甚至创建)这个内部列表的需要,它还有一个标志,指示列表是否是最新的,并且只在必要时检查它并重建列表。
为了维护标志,每个继承的字典方法可能会改变(或改变)字典的内容,用helper函数“包装”,重新设置标志,然后链接到正常的字典方法来实际执行操作。将它们安装到类中只需要将方法的名称放在两个列表中的一个中,然后在创建类后立即将它们传递给辅助工具。
by __indexes__ you mean keys ??? – mouad 2010-11-16 13:08:36
@singularity:看看OP的过去的问题http://stackoverflow.com/questions/4181367/python-possible-to-filter-dict你应该是对的。 – kennytm 2010-11-16 13:12:54
没有,没有按键,只是经过一些排序(或根本没有排序),我想要字典的第一/最后/中间部分... – 2010-11-16 13:14:35