正如其他人所提到的,在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