2012-08-15 31 views
8

Đối với container built-in python (list, tuple, vv) các nhà điều hành in tương đương với any(y == item for item in container) với sự báo trước rằng phương pháp cũ là nhanh hơn (và đẹp hơn):Danh sách python có tương đương với __contains__ để kiểm tra danh tính không?

In [13]: container = range(10000) 
In [14]: %timeit (-1 in container) 
1000 loops, best of 3: 241 us per loop 
In [15]: %timeit any(-1 == item for item in container) 
1000 loops, best of 3: 1.2 ms per loop 

Có một tương đương với any(y is item for item in container) ? Đó là, một thử nghiệm sử dụng is thay vì ==?

Trả lời

6

Không, không có. Toán tử is là không cần thiết thường xuyên để biện minh cho việc phải duy trì một phương pháp tối ưu hóa C và thêm nhầm lẫn vào API python.

Kiểm tra in cho danh sách và bộ dữ liệu thực hiện tìm kiếm đầy đủ tương tự như any, mặc dù trong C, btw. Tuy nhiên, trong các bộ, phép thử sử dụng thuật toán lưu trữ hiệu quả bên dưới vùng chứa và tìm kiếm mất thời gian không đổi trong trường hợp dự kiến. Đối với cả hai bộ và ánh xạ, các khóa được cho là có giá trị băm ổn định, mà trong hầu hết các trường hợp, có nghĩa là không cần đến is.

Vì vậy, đúng chính tả là:

# For sequences 
any(y is item for item in container) 

# For sets, short circuit first for the not-present case: 
# (note that you normally should not need this as you are supposed to rely on the hash) 
y in setcontainer and any(y is item for item in setcontainer) 

# For mappings, y is a key 
y in mapping 

# For mappings, y is a value, and you do not have a key, fall back to any 
any(y is item for item in mapping.itervalues()) 
+5

Trong thực tế, tôi đã luôn luôn coi nó là một lỗ hổng tài liệu mà các phương pháp 'list.index' và' list.count' vv nói điều gì đó để tác động " Trả về chỉ mục trong danh sách mục đầu tiên có giá trị * là * x. Đó là lỗi nếu không có mục nào " – mgilson

+0

Nhưng ngay cả với các bộ,' in' kiểm tra giá trị băm không * đảm bảo * rằng các đối tượng khác nhau. xem xét 'a = (1,2,3); c = (1,2,3); c là a; s = set ([a]); c trong s'. Mặc dù, hiện tại, tôi không thể nghĩ ra một thời điểm mà điều này sẽ quan trọng. – mgilson

+0

Không, chỉ cần chỉ ra rằng toán tử 'in' trên tập hợp và dấu gạch ngang không có * quét *. –

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