2011-08-05 54 views
6

Tôi có một cuốn từ điển có dạng sau:python tương đương tương đương

{ <Category('Simulate', 'False', 'False', 'False', 'INTERMEDIATE')>: {'link': u'/story/4/tvb-adapters-simulator-simulatorAdapter/SimulatorAdapter', 'name': u'Simulate'}, 
    <Category('View Results', 'True', 'False', 'True', 'INTERMEDIATE')>: {'link': '/story/step/3', 'name': u'View Results'}, 
    <Category('Analyze', 'True', 'False', 'False', 'FINAL')>: {'link': '/story/step/2', 'name': u'Analyze'}} 

loại là một lớp đại diện cho một thể hiện từ một cơ sở dữ liệu. Bây giờ tôi có ví dụ sau:

<Category('Analyze', 'True', 'False', 'False', 'FINAL')> 

Bây giờ đây không phải là trường hợp tương tự. Bằng cách này tôi có nghĩa là, tôi nhận được tất cả các giá trị từ cơ sở dữ liệu và tạo từ điển. Sau đó, sau một thời gian tôi nhận được một id và lấy dụ từ cơ sở dữ liệu. Bây giờ họ không phải là cùng một đối tượng. Bây giờ tôi phải kiểm tra xem nó có trong từ điển không, nhưng:

instance in disctionary 

Sẽ trả về false. Bây giờ tôi có thể đi theo cách xấu xí và lặp qua kiểm tra từ điển nếu tất cả các giá trị phù hợp, tuy nhiên liệu Python có một cách thông minh hơn để làm điều này? Tôi có nghĩa là một cái gì đó giống như tương đương với so sánh trong Java?

+1

Tôi thất bại trong việc nhận ra Python là hợp lệ này. Cái này là gì < '? –

+2

Đó là dict được in đẹp của anh ấy, và tùy chỉnh sử dụng các dấu ngoặc nhọn trong repr() của một lớp. – pyroscope

+0

@pyroscope: Cảm ơn! Học một cái gì đó mới mỗi ngày ... –

Trả lời

9

Đầu tiên: sử dụng TrueFalse (thuộc tính boolean) thay vì 'True''False' (thuộc tính chuỗi).

Nói chung, bạn có thể làm mọi thứ có thể so sánh được bằng Python. Bạn chỉ cần xác định các phương pháp cụ thể (như __eq__, __lt__, v.v.) cho lớp học của bạn.

Vì vậy, chúng ta hãy nói rằng tôi muốn so sánh trường hợp của lớp A, và việc so sánh nên chỉ case-insensitive string so sánh s thành viên:

class A(object): 
    def __init__(self, s=''): 
     self.s = s 

    def __eq__(self, other): 
     return self.s.lower() == other.s.lower() 

a = A('aaaa') 
b = A('AAAA') 
print a == b # prints True 
b = A('bbbb') 
print a == b # prints False 
+0

Cảm ơn các yếu tố đầu vào. Là những gì tôi đang tìm kiếm. – Bogdan

2

Thay vì sử dụng trường hợp của Category (ví dụ Category('Analyze', 'True', 'False', 'False', 'FINAL')) như các phím trong từ điển của bạn, có vẻ như bạn nên sử dụng các tuple liên quan (ví dụ ('Analyze', 'True', 'False', 'False', 'FINAL')).

Nếu bạn thực sự muốn sử dụng thể hiện của Category làm các khóa trong từ điển, bạn sẽ cần xác định cả hai phương pháp __hash____eq__. Ví dụ:

class Category(object): 
    def __init__(self,*args): 
     self.args=args 
    def __hash__(self): 
     # Note that this assumes that Category's hash value is immutable 
     # i.e. self.args does not change. 
     return hash(self.args) 
    def __eq__(self,other): 
     return self.args == other.args 

a=Category('Analyze', 'True', 'False', 'False', 'FINAL') 
b=Category('Analyze', 'True', 'False', 'False', 'FINAL') 

mydict={a:1} 

ab những trường khác nhau, vì vậy họ có khác nhau id s, nhưng giá trị băm của họ đều giống nhau:

assert id(a) != id(b) 
assert hash(a)==hash(b) 

Điều này cho thấy b là một chìa khóa có thể chấp nhận trong mydict:

print(mydict[a]) 
# 1 
print(mydict[b]) 
# 1 

PS. Đừng bận tâm với __cmp__. In Python 3:

Các CMP() chức năng nên được coi như biến mất, và __cmp__() phương pháp đặc biệt là không còn được hỗ trợ. Sử dụng __lt__() để phân loại, __eq__() với __hash__() và các so sánh khác nếu cần.

+0

Tôi đang sử dụng các bộ dữ liệu mà chỉ là kết quả của một bản in sẵn. – Bogdan

1

Có thể có các phím tắt, như sử dụng các bộ, nhưng câu trả lời chung cho câu hỏi của bạn là: thực hiện __eq__() cho lớp học của bạn, do đó CMP() sẽ sử dụng nó thay vì thử nghiệm cho bản sắc.

1

Đối in và toán tử so sánh khác để làm việc, bạn có để triển khai __hash____cmp__ (hoặc phương pháp so sánh "phong phú" như __eq__). Xem Python reference.

1

Vì bạn có thể đặt trường hợp danh mục của mình thành một chế độ độc tài, bạn phải ghi đè __hash__ rồi. Tất cả bạn cần bây giờ là __eq__:

class Category(object): 
    # you must have overwritten `__hash__` like this already 
    def __hash__(self): 
     return hash((self.attr1, self.attr2, ...)) 

    # now you just need tis 
    def __eq__(self, other): 
     return isinstance(other, Category) and \ 
       (self.attr1, self.attr2, ...) == (other.attr1, other.attr2, ...) 

gì bạn thực sự cần làm là ném mà cả lớp đi và sử dụng một collections.namedtuple thay vì:

Category = collections.namedtuple('Category', 'attr1 attr2 attr3') 
+0

+1 cho bộ sưu tập.namedtuple. – user9876

Các vấn đề liên quan