2010-02-24 35 views
20

tôi phải giải quyết bài tập này:Python: Kéo dài tuổi 'dict' lớp

điển Python không giữ gìn trật tự của dữ liệu được chèn cũng không lưu trữ các dữ liệu được sắp xếp theo chìa khóa. Viết một phần mở rộng cho lớp dict mà các cá thể của nó sẽ giữ cho dữ liệu được sắp xếp theo giá trị khóa của chúng. Lưu ý rằng thứ tự phải được bảo toàn khi các phần tử mới được thêm vào.

Làm cách nào để mở rộng dict? Tôi có cần truy cập vào mã nguồn cho loại dict không?

+2

hmmm ... bài tập về nhà? – jldupont

Trả lời

27

Bạn có thể phân lớp dict hoặc UserDict, vì van đã nói về UserDict, hãy xem dict.

Nhập help(dict) vào thông dịch viên và bạn sẽ thấy danh sách các phương pháp lớn. Bạn sẽ cần phải ghi đè lên tất cả các phương thức sửa đổi dict cũng như các phương thức lặp lại trên dict.

Phương pháp mà sửa đổi dict bao gồm __delitem__, __setitem__, clear, vv

Phương pháp đó lặp dict bao gồm __iter__, keys, values, items, vv

này sẽ giúp bạn bắt đầu

>>> class odict(dict): 
...  def __init__(self, *args, **kw): 
...   super(odict,self).__init__(*args, **kw) 
...   self.itemlist = super(odict,self).keys() 
...  def __setitem__(self, key, value): 
...   # TODO: what should happen to the order if 
...   #  the key is already in the dict  
...   self.itemlist.append(key) 
...   super(odict,self).__setitem__(key, value) 
...  def __iter__(self): 
...   return iter(self.itemlist) 
...  def keys(self): 
...   return self.itemlist 
...  def values(self): 
...   return [self[key] for key in self] 
...  def itervalues(self): 
...   return (self[key] for key in self) 
... 
>>> od = odict(a=1,b=2) 
>>> print od 
{'a': 1, 'b': 2} 
>>> od['d']=4 
>>> od['c']=3 
>>> print od # look at the `__str__` and `__repr__` methods 
{'a': 1, 'c': 3, 'b': 2, 'd': 4} 
>>> print od.keys() 
['a', 'b', 'd', 'c'] 
>>> print od.values() 
[1, 2, 4, 3] 
+0

bất kỳ cơ hội nào của ví dụ làm việc với python 3? Tôi bắt đầu thay đổi 'self.itemlist.append (key)' bằng 'set (self.itemlist) .add (key)' để làm cho nó hoạt động, nhưng thứ tự không được giữ nguyên nữa – z3d0

+0

@ z3d0r, Trong Python3, '.keys () 'không còn trả về một danh sách nữa, vì vậy bạn cần sử dụng' self.itemlist = list (super (odict, self) .keys()) 'trong phương thức' __init__'. –

+0

cảm ơn, tôi cũng nhận thấy rằng các phương thức 'values ​​()' và 'itervalues ​​()' không còn tồn tại nữa, và rằng 'keys()' là một tập hợp chứ không phải một danh sách, vì vậy sẽ 'def keys (self): return set (self.itemlist) 'là đúng? Vẫn đang làm việc vì nó không được giữ nguyên – z3d0

9

Việc triển khai dict sẽ không giúp bạn thực hiện nhiệm vụ. Những gì bạn muốn là một lớp có cùng giao diện như dict, nhưng thực hiện khác. That will require to implement methods like __getitem__, __setitem__, etc. Nếu bạn Google cho "orderdict", bạn sẽ tìm thấy rất nhiều ví dụ.

+2

Đọc các bộ sưu tập.ABC thông tin về việc mở rộng 'Ánh xạ' để triển khai từ điển được sắp xếp.http://docs.python.org/library/collections.html#abcs-abstract-base-classes. –

5

Nếu bạn sử dụng python 2.7+, hãy xem collections.OrderedDict.
Nếu không, hãy quay lại (sao chép nguồn) hoặc xem Recipe 576693: Ordered Dictionary for Py2.4 (Python).

Nhưng nếu bạn thực sự cần mở rộng dict, hãy bắt đầu với UserDict, nguồn mà bạn có thể tìm thấy trong /lib/UserDict.py phân phối python của bạn.

+0

@ user280560: Nếu bạn làm điều này, hãy chắc chắn rằng bạn nói với người hướng dẫn của bạn, nơi bạn nhận được mã từ, vì bạn đã không viết nó, nhưng downlaoded nó. –

+0

@ S.Lott: Tôi tưởng tượng rằng anh ấy không được phép sao chép và dán, và họ đang sử dụng 2.5/2.6. – voyager

+2

Tôi không nghĩ rằng nhiệm vụ là để thực hiện 'OrderedDict', hoặc, kể từ đó bảo tồn trật tự _insertion_ hơn là duy trì thứ tự khóa được sắp xếp. –

5

Tin vui: vấn đề không khó chút nào.

Để poke xung quanh và thấy ruột của một class bạn có thể sử dụng

>>> dir(dict) 
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 

help(dict), trong đó có một tài liệu hướng dẫn tương tác rất hoàn chỉnh, nhưng tất nhiên bạn cũng có thể truy cập thậm chí hoàn chỉnh hơn online documentation .

Khi bạn đã nắm bắt được những gì dict thực hiện sau hậu trường, bạn nên tìm hiểu về inheritance in Python.

Nếu bạn gặp khó khăn lần this site để có được một số ý tưởng, nhưng không sao chép/dán, giáo viên của bạn sẽ không nhìn thấy nó vui lòng.