2012-07-09 17 views
6

thể trùng lặp:
'has_key()' or 'in'?hiệu quả giữa dict.has_key và quan trọng trong dict bằng Python

Trong Python, đang có hai cách để quyết định liệu một key là trong một dict :

if dict.has_key(key)if key in dict

Người nào đó nói với tôi rằng thứ hai chậm hơn người đầu tiên vì từ khóa in làm cho biểu thức lặp lại trên dict, vì vậy nó sẽ chậm hơn so với thay thế has_key, rõ ràng sử dụng hàm băm để đưa ra quyết định.

Vì tôi rất nghi ngờ sự khác biệt, vì tôi nghĩ Python đủ thông minh để dịch từ khóa in trước dict thành một số cách băm, tôi không thể tìm thấy bất kỳ khiếu nại chính thức nào về điều này.

Vì vậy, có sự khác biệt hiệu quả nào giữa hai loại này không?

Cảm ơn.

Trả lời

8

Cả hai thao tác này đều thực hiện tương tự: kiểm tra bảng băm được triển khai trong dict cho khóa. Sẽ không lặp lại toàn bộ từ điển. Lưu ý rằng for x in dict khác với if x in dict. Cả hai đều sử dụng từ khóa in, nhưng là các hoạt động khác nhau.

Từ khóa in trở thành cuộc gọi trên dict.__contains__, mà dict có thể thực hiện theo cách mà nó thích.

Nếu có sự khác biệt về thời gian của các hoạt động này, nó sẽ rất nhỏ và sẽ phải thực hiện với phí gọi hàm của has_key.

BTW, tùy chọn chung là dành cho key in dict như một biểu hiện rõ ràng hơn về mục đích hơn dict.has_key(key). Lưu ý rằng tốc độ không có gì để làm với sở thích. Khả năng đọc là quan trọng hơn tốc độ trừ khi bạn biết bạn đang ở trong con đường quan trọng.

+2

.... tất cả điều này và ngoài ra, 'has_key()' không được dùng nữa và không còn được sử dụng nữa. :) – jonesy

3

D.has_key thực sự là chậm hơn do sự gọi hàm:

>>> D = dict((x, y) for x, y in zip(range(1000000), range(1000000))) 
>>> from timeit import Timer 
>>> t = Timer("1700 in D", "from __main__ import D") 
>>> t.timeit() 
0.10631704330444336 
>>> t = Timer("D.has_key(1700)", "from __main__ import D") 
>>> t.timeit() 
0.18113207817077637 
+1

Đó là "hơi"? –

+0

Cũng xem xét rằng timeit chạy tuyên bố một triệu lần, và số lượng là trong vài giây, sự khác biệt * tuyệt đối * thời gian là khá nhỏ – jterrace

+0

Một cái gì đó như 80 nano giây .. – jterrace

3

has_key không phải là một sự thay thế. Nó không được chấp nhận. Không sử dụng nó. (Dù chậm hơn thế nào)

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