Bạn có thể cải thiện vấn đề bằng cách tạo danh sách từ khóa của bạn dưới dạng cụm từ thông dụng.
Điều này có thể cho phép chúng được kiểm tra song song, nhưng sẽ phụ thuộc rất nhiều vào từ khóa (ví dụ: một số công việc có thể được sử dụng lại cho "hello" và "hell" thay vì tìm kiếm mọi cụm từ ngay từ đầu . cho mỗi từ
Bạn có thể làm điều này bằng cách thực hiện:
import re
keyword_re = re.compile("|".join(map(re.escape, keywords)))
Sau đó:
>>> bool(keyword_re.search('hello, world'))
True
>>> bool(keyword_re.search('hi, earth'))
False
(Nó sẽ thực sự trả về một đối tượng phù hợp trên được tìm thấy, và Không nếu không tìm thấy - điều này có thể hữu ích nếu bạn cần biết từ khóa nào phù hợp)
Tuy nhiên, số tiền (nếu có) lợi ích này bạn sẽ phụ thuộc vào từ khóa. Nếu bạn chỉ có một hoặc hai, hãy giữ cách tiếp cận hiện tại của bạn. Nếu bạn có một danh sách lớn, nó có thể đáng tring và profiling để xem cái nào hoạt động tốt hơn.
[Chỉnh sửa] Để tham khảo, dưới đây là cách các phương pháp làm ví dụ của bạn:
good1 good2 good3 bad1 bad2
original : 0.206 0.233 0.229 0.390 63.879
gnud (join) : 0.257 0.347 4.600 0.281 6.706
regex : 0.766 1.018 0.397 0.764 124.351
regex (join) : 0.345 0.337 3.305 0.481 48.666
Rõ ràng đối với trường hợp này, cách tiếp cận của bạn thực hiện tốt hơn nhiều so với cái regex. Cho dù điều này sẽ luôn luôn là trường hợp phụ thuộc rất nhiều vào số lượng và độ phức tạp của các từ khóa, và các dữ liệu đầu vào sẽ được kiểm tra. Đối với số lượng lớn từ khóa và danh sách dài hoặc cụm từ hiếm khi phù hợp, regex có thể hoạt động tốt hơn, nhưng làm nhận thông tin thời gian và có thể thử thậm chí tối ưu hóa đơn giản hơn (như chuyển các từ phổ biến nhất sang trước danh sách từ khóa của bạn). Đôi khi cách tiếp cận đơn giản nhất thực sự là tốt nhất.
[Edit2] Cập nhật bảng với gnud's solution và cách tiếp cận tương tự trước khi áp dụng các regex. Tôi cũng đã thêm 2 thử nghiệm mới:
good_data3 = good_data2 * 500 # 1000 items, the first of which matches.
bad_data2 = bad_data * 500 # 1000 items, none of which matches.
Hiển thị các điểm mạnh và điểm yếu khác nhau.Việc tham gia không tồi tệ hơn khi một kết quả phù hợp sẽ được tìm thấy ngay lập tức (vì có một chi phí trả trước luôn được trả trong danh sách - đây là trường hợp tốt nhất có thể cho phương pháp tìm kiếm tuyến tính), tuy nhiên đối với danh sách không khớp, nó sẽ thực hiện tốt hơn. Nhiều tốt hơn khi có một số lượng lớn các mục trong danh sách.case).
Giải pháp hay, tôi đã nghĩ chính xác điều đó. Nó nên được khá nhanh so với regexes, bởi vì các __contains__ kiểm tra được thực hiện với một Boyer-Moore sửa đổi và do đó nên bỏ qua độc đáo trên các ký tự phân cách. –
Ý tưởng hay, và nó có hiệu ứng * rất rõ ràng trên các danh sách lớn - có lẽ như Torsten nói vì python có thể tái sử dụng các bảng tìm kiếm mà nó tạo ra thay vì ném chúng đi và tái tạo chúng cho mọi mục danh sách. Tôi sẽ cập nhật số liệu thời gian của mình. – Brian
Tham gia mảng là một ý tưởng tuyệt vời! Tôi quyết định sử dụng kết hợp này với gợi ý của S.Lott về hàm any(). Cảm ơn! –