Cách kiểm tra xem một chuỗi có chứa một phần tử từ danh sách trong Python không


217

Tôi có một cái gì đó như thế này:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

Tôi đang tự hỏi điều gì sẽ là cách thanh lịch hơn để làm điều này trong Python (mà không sử dụng vòng lặp for)? Tôi đã nghĩ về một cái gì đó như thế này (như từ C / C ++), nhưng nó không hoạt động:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

Chỉnh sửa: Tôi hơi bị buộc phải giải thích điều này khác với câu hỏi dưới đây được đánh dấu là trùng lặp tiềm năng (vì vậy tôi đoán nó không bị đóng).

Sự khác biệt là, tôi muốn kiểm tra xem một chuỗi có phải là một phần của danh sách các chuỗi hay không trong khi câu hỏi khác là kiểm tra xem một chuỗi từ danh sách các chuỗi có phải là chuỗi con của một chuỗi khác hay không. Tương tự, nhưng không hoàn toàn giống nhau và vấn đề ngữ nghĩa khi bạn đang tìm kiếm một câu trả lời trực tuyến IMHO. Hai câu hỏi này thực sự đang tìm cách giải quyết vấn đề ngược lại của nhau. Các giải pháp cho cả hai hóa ra là như nhau mặc dù.


Câu trả lời:


418

Sử dụng một trình tạo cùng với any, mà ngắn mạch trên True đầu tiên:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

EDIT: Tôi thấy câu trả lời này đã được OP chấp nhận. Mặc dù giải pháp của tôi có thể là giải pháp "đủ tốt" cho vấn đề cụ thể của anh ấy và là một cách tổng quát tốt để kiểm tra xem có bất kỳ chuỗi nào trong danh sách được tìm thấy trong một chuỗi khác hay không, hãy nhớ rằng đây là tất cả những gì giải pháp này thực hiện. Nó không quan tâm WHERE chuỗi được tìm thấy, ví dụ như ở phần cuối của chuỗi . Nếu điều này là quan trọng, như thường xảy ra với các url, bạn nên tìm đến câu trả lời của @Wladimir Palant, hoặc bạn có nguy cơ bị dương tính giả.


1
đây chính xác là những gì tôi đang tìm kiếm. trong trường hợp của tôi, nó không quan trọng ở chỗ trong chuỗi là phần mở rộng. cảm ơn
pootzko

Đề nghị tuyệt vời. Sử dụng ví dụ này, đây là cách tôi kiểm tra xem có bất kỳ đối số nào khớp với các cờ trợ giúp nổi tiếng không: any ([x.lower () trong ['-?', '- h', '- help', '/ h '] cho x trong sys.argv [1:]])
Phòng thí nghiệm của AX

@ AX-Labs sử dụng khả năng hiểu danh sách bên trong anysẽ phủ nhận một số lợi ích có thể có mà ngắn mạch cung cấp, bởi vì toàn bộ danh sách sẽ phải được xây dựng trong mọi trường hợp. Nếu bạn sử dụng biểu thức không có dấu ngoặc vuông ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])), x.lower() in [...]phần sẽ chỉ được ước tính cho đến khi tìm thấy giá trị True.
Lauritz V. Thaulow

5
Và nếu tôi muốn biết ext là gì khi any () trả về True?
Peter Senna

@PeterSenna: any()sẽ chỉ trả về đúng hoặc sai , nhưng hãy xem câu trả lời hiểu danh sách của @psun bên dưới với sửa đổi này:print [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
Điều này thật thông minh - Tôi không biết các bộ dữ liệu có thể làm điều đó!, nhưng nó chỉ hoạt động khi chuỗi con của bạn được neo vào một đầu của chuỗi.
Dannid

3
Cách mát mẻ. Tôi chỉ ước có một cái gì đó như "chứa" thay vì chỉ bắt đầu hoặc kết thúc
BrDaHa

@BrDaHa bạn có thể sử dụng 'in' để chứa. nếu 'chuỗi' trong danh sách:
Shekhar Samanta

@ShekharSamanta chắc chắn, nhưng điều đó không giải quyết được vấn đề kiểm tra xem một trong nhiều thứ có trong một chuỗi hay không, đó là câu hỏi ban đầu.
BrDaHa

Có trong trường hợp đó, chúng ta có thể sử dụng: if any (phần tử trong chuỗi.split ('any delmiter') cho phần tử trong danh sách) & cho chuỗi nếu có (phần tử trong chuỗi cho phần tử trong danh sách)
Shekhar Samanta

21

Tốt hơn là phân tích URL đúng cách - theo cách này bạn có thể xử lý http://.../file.doc?foohttp://.../foo.doc/file.exechính xác.

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

Sử dụng hiểu danh sách nếu bạn muốn một giải pháp dòng duy nhất. Đoạn mã sau trả về một danh sách chứa url_ chuỗi khi nó có các phần mở rộng .doc, .pdf và .xls hoặc trả về danh sách trống khi nó không chứa phần mở rộng.

print [url_string for extension in extensionsToCheck if(extension in url_string)]

LƯU Ý: Điều này chỉ để kiểm tra xem nó có chứa hay không và không hữu ích khi người ta muốn trích xuất từ ​​chính xác khớp với các phần mở rộng.


Điều này dễ đọc hơn anygiải pháp, theo ý kiến ​​của tôi, đây là một trong những giải pháp tốt nhất có thể.
Dmitry Verhoturov

Theo any()tôi, giải pháp này vượt trội hơn giải pháp vì nó có thể được thay đổi để trả về giá trị khớp cụ thể, như vậy: print [extension for extension in extensionsToCheck if(extension in url_string)](xem câu trả lời của tôi để biết thêm chi tiết và cách trích xuất từ phù hợp cũng như mẫu từ url_ chuỗi)
Dannid

2

Kiểm tra nếu nó phù hợp với regex này:

'(\.pdf$|\.doc$|\.xls$)'

Lưu ý: nếu tiện ích mở rộng của bạn không ở cuối url, hãy xóa các $ký tự, nhưng nó làm yếu đi một chút


1
Đó là một URL, nếu nó có một chuỗi truy vấn thì sao?
Wladimir Palant

nhập lại re.search (mẫu, your_ chuỗi)
juankysmith

trong khi câu trả lời này hoạt động cho trường hợp được chỉ định, nó không thể mở rộng hoặc chung chung. bạn cần một regex dài cho mọi mẫu bạn muốn khớp.
Dannid

1

Đây là một biến thể của câu trả lời hiểu danh sách được đưa ra bởi @psun.

Bằng cách chuyển đổi giá trị đầu ra, bạn thực sự có thể trích xuất mẫu phù hợp từ mức độ hiểu danh sách (điều không thể với any()cách tiếp cận của @ Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

['.doc'] `

Ngoài ra, bạn có thể chèn một biểu thức chính quy nếu bạn muốn thu thập thông tin bổ sung sau khi đã biết mẫu phù hợp (điều này có thể hữu ích khi danh sách các mẫu được phép quá dài để viết thành một mẫu biểu thức chính)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.