2012-06-14 17 views
5

Như tiêu đề nói, tôi có một danh sách các từ, như stopWords = ["the", "and", "with", etc...] và tôi nhận được văn bản như "Giết con cáo và chó". Tôi muốn đầu ra như "Giết con chó con cáo" rất hiệu quả và nhanh chóng. Làm thế nào tôi có thể làm được điều này (tôi biết tôi có thể lặp sử dụng một vòng lặp for, nhưng thats không phải là rất hiệu quả)Nếu tôi có một danh sách các từ, làm thế nào tôi có thể kiểm tra xem chuỗi không chứa bất kỳ từ nào trong danh sách và có hiệu quả không?

Trả lời

8

Sự cải thiện imporant nhất là để làm cho stopWords là set. Điều này có nghĩa là tra cứu sẽ rất nhanh

stopWords = set(["the", "and", "with", etc...]) 
" ".join(word for word in msg.split() if word not in stopWords) 

Nếu bạn chỉ muốn biết nếu một trong các từ dừng là trong văn bản

if any(word in stopWords for word in msg.split()): 
    ... 
+0

Nó có hiệu quả hơn việc tạo một regex không? – mlt

+0

@mlt, có thể không. Công việc rất khác với điều này mà khó đoán. Bạn nên viết câu trả lời bằng cách sử dụng regexp –

1

Sử dụng list comprehension:

stopWords = ["the", "and", "with"] 
msg = "kill the fox and the dog" 

' '.join([w for w in msg.split() if w not in stopWords]) 

cho:

'kill fox dog' 
+1

'w không stopWords' sẽ nhận được chậm hơn như từ dừng được nữa vì nó đã để lặp qua danh sách để kiểm tra mỗi một. Đây là lý do tại sao làm cho stopWords một bộ là quan trọng –

+0

@gnibbler Ok, do đó, lưu ý, cảm ơn. Luôn vui khi học một cái gì đó mới (Tôi không sử dụng bộ gần như thường xuyên) – Levon

0
  1. Đặt danh sách ban đầu của bạn từ trong từ điển.
  2. Lặp lại các ký tự trong chuỗi đã cho, sử dụng dấu cách làm dấu phân tách cho một từ. Tra cứu từng từ trong từ điển.
3

Với Python, thao tác nhanh nhất sẽ đặt "stopwords" thành một tập hợp thay vì danh sách và kiểm tra trực tiếp thành viên bằng "x in stopwords". Cấu trúc này được thiết kế để nhanh chóng cho loại hoạt động này.

See the set documentation

0

Có từ dừng của bạn trong một set() (như những người khác đã gợi ý), tích lũy Nói cách khác bạn thành một công tác thiết lập sau đó chỉ cần lấy chênh lệch bộ sử dụng working = working - stopWords ... để có một thiết lập làm việc với tất cả các stopWords được lọc ra khỏi nó. Hoặc chỉ để kiểm tra sự tồn tại của những từ đó sử dụng một điều kiện. Ví dụ:

#!python 
stopWords = set('the a an and'.split()) 
working = set('this is a test of the one working set dude'.split()) 
if working == working - stopWords: 
    print "The working set contains no stop words" 
else: 
    print "Actually, it does" 

Thực tế, có cấu trúc dữ liệu hiệu quả hơn, chẳng hạn như một trie mà có thể được sử dụng cho lớn, tương đối dày đặc, tập hợp từ dừng lại. Bạn có thể tìm thấy các mô-đun trie cho Python, mặc dù tôi không thấy bất kỳ phần mở rộng nào được viết dưới dạng nhị phân (C) và tôi tự hỏi đâu là điểm chéo giữa một trie được triển khai bằng Python thuần túy so với sử dụng hỗ trợ set() của Python. (Cũng có thể là một trường hợp tốt cho Cython, mặc dù).

Thực tế tôi thấy rằng ai đó đã giải quyết riêng câu hỏi đó tại đây SO: How do I create a fixed length mutable array of python objects in cython. Cuối cùng, tất nhiên, bạn nên tạo phiên bản dựa trên tập hợp đơn giản, kiểm tra và cấu hình nó, sau đó, nếu cần thiết, hãy thử các biến thể trie và Cython-trie như những cải tiến có thể có.

0

Thay vào đó, bạn có thể lắp ráp danh sách của mình trong một regex và thay thế các từ dừng cùng với các khoảng không gian xung quanh bằng một khoảng trắng.

import re 
stopWords = ["the", "and", "with"] 
input = "Kill the fox and dog" 
pattern = "\\s{:s}\\s".format("\\s|\\s".join(stopWords)) 
print(pattern) 
print(re.sub(pattern, " ", input)) 

chí đầu ra

\sthe\s|\sand\s|\swith\s 
Kill fox dog 
Các vấn đề liên quan