Như những người khác đã đề cập, trong từ điển Python vốn đã không có thứ tự. Tuy nhiên, tại bất kỳ thời điểm nào, danh sách các khóa hiện tại hoặc các cặp khóa, giá trị có thể thu được bằng cách sử dụng các phương thức keys()
hoặc items()
của chúng.Một vấn đề có thể xảy ra khi sử dụng các danh sách này không chỉ là nội dung của chúng mà cả thứ tự nó được trả về sẽ thay đổi nếu từ điển đã được sửa đổi (hoặc biến đổi) kể từ lần cuối cùng chúng được sử dụng. Điều này có nghĩa là bạn thường không thể lưu trữ và sử dụng lại danh sách trừ khi bạn cập nhật nó mỗi khi từ điển được thay đổi chỉ trong trường hợp bạn sẽ cần nó.
Để làm cho phương pháp này dễ quản lý hơn, bạn có thể kết hợp từ điển và danh sách phụ vào lớp dẫn xuất mới, đồng thời cung cấp phương thức get_range()
sử dụng nội dung hiện tại của danh sách. Dưới đây là mã mẫu cho biết cách thực hiện điều này. Nó dựa trên ý tưởng tôi nhận được từ mã số trong 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'}
Ý tưởng cơ bản là để lấy được một lớp mới từ dict
rằng cũng có một danh sách nội dung nội bộ để sử dụng theo phương pháp mới get_range()
nó quy định rằng đối tượng từ điển thông thường thì không. Để giảm thiểu nhu cầu cập nhật (hoặc thậm chí tạo) danh sách nội bộ này, nó cũng có một lá cờ cho biết danh sách có được cập nhật hay không và chỉ kiểm tra nó và xây dựng lại danh sách khi cần thiết.
Để duy trì cờ, mỗi phương pháp từ điển kế thừa có khả năng thay đổi (hoặc biến đổi) nội dung của từ điển được "gói" với chức năng trợ giúp, đặt lại cờ và sau đó xâu thành phương pháp từ điển thông thường để thực sự thực hiện thao tác. Việc cài đặt chúng vào lớp chỉ đơn giản là đặt tên của các phương thức vào một trong hai danh sách và sau đó chuyển chúng một lần vào một tiện ích phụ trợ ngay sau khi tạo lớp.
bởi __indexes__ bạn có nghĩa là khóa ??? – mouad
@singularity: Nhìn vào câu hỏi trong quá khứ của OP http://stackoverflow.com/questions/4181367/python-possible-to-filter-dict bạn nên nói đúng. – kennytm
KHÔNG, không phải bằng phím, chỉ sau khi sắp xếp (hoặc không phân loại gì cả), tôi muốn phần đầu/cuối/giữa của dict ... –