2012-03-08 30 views
6

Tôi có một danh sách các chuỗi, từ đó tôi muốn định vị mọi dòng có 'http: //' trong đó, nhưng không có 'lulz', ' lmfao ',' .png 'hoặc bất kỳ mục nào khác trong danh sách các chuỗi trong đó. Làm thế nào tôi sẽ đi về điều này?Nếu chuỗi không chứa bất kỳ danh sách các chuỗi nào trong python

Bản năng của tôi bảo tôi sử dụng cụm từ thông dụng, nhưng tôi có phản đối về mặt đạo đức đối với phù thủy.

Trả lời

10

Dưới đây là một lựa chọn đó là khá mở rộng nếu danh sách các chuỗi để loại trừ là lớn:

exclude = ['lulz', 'lmfao', '.png'] 
filter_func = lambda s: 'http://' in s and not any(x in s for x in exclude) 

matching_lines = filter(filter_func, string_list) 

Danh sách thay thế hiểu:

matching_lines = [line for line in string_list if filter_func(line)] 
+0

Tuyệt vời! Tôi có thể sử dụng lambda! Tôi biết nó tồn tại vì một lý do nào đó! – directedition

+1

Bạn không cần phải làm như vậy. 'lambda' cho phép bạn định nghĩa hàm inline thay vì thiết lập một biến' filter_func'; nhưng bạn có thể dễ dàng viết 'def filter_func (s): trả về 'http: //' trong s và không phải bất kỳ (x trong s cho x trong loại trừ)'. Hãy nhớ rằng, các hàm là các đối tượng. –

+0

Tôi thậm chí có thể nói đây là một cách sử dụng không phù hợp của 'lambda'. Không có lý do để thích nó với một 'def' ở đây. – wim

2

Hãy thử điều này:

for s in strings: 
    if 'http://' in s and not 'lulz' in s and not 'lmfao' in s and not '.png' in s: 
     # found it 
     pass 

tùy chọn khác, nếu bạn cần lựa chọn của bạn linh hoạt hơn:

words = ('lmfao', '.png', 'lulz') 
for s in strings: 
    if 'http://' in s and all(map(lambda x, y: x not in y, words, list(s * len(words))): 
     # found it 
     pass 
+0

Đó là cách tiếp cận đầu tiên của tôi. Nhưng khi danh sách của tôi lớn lên và dòng trở nên khó sử dụng, tôi đã hy vọng có một cách tốt hơn. – directedition

+1

Điều đó có thể bị mất nếu anh ta muốn mở rộng danh sách các từ dừng. Làm thế nào bạn sẽ thay đổi cách tiếp cận của bạn? Nhưng vẫn còn, 1 cho các giải pháp đơn giản. – prelic

3

này là gần như tương đương với giải pháp FJ, nhưng sử dụng generator expressions thay vì biểu thức lambda và chức năng lọc:

haystack = ['http://blah', 'http://lulz', 'blah blah', 'http://lmfao'] 
exclude = ['lulz', 'lmfao', '.png'] 

http_strings = (s for s in haystack if s.startswith('http://')) 
result_strings = (s for s in http_strings if not any(e in s for e in exclude)) 

print list(result_strings) 

Khi tôi chạy nó này in:

['http://blah'] 
+0

+1 cho máy phát điện. Tuy nhiên, lưu ý rằng bạn có thể làm điều này như một (n gần) một lớp lót: 'result_strings = [s cho s trong haystack nếu s.startswith ('http: //') và không phải bất kỳ (e trong s cho e trong loại trừ)] '. Nó cần một ngắt dòng để phù hợp với 80 cột (mỗi hướng dẫn phong cách nhất), nhưng tôi sẽ cho rằng nó là hơi dễ dàng hơn để làm theo hơn so với phiên bản hai máy phát điện. timeit cũng báo cáo rằng đây là một chút công bằng nhanh hơn, và cũng nhanh hơn một chút so với phiên bản bộ lọc của F.J (trong đó, IMO, là khó khăn nhất để làm theo trong ba). – lvc

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