2013-08-21 37 views
153

Cách viết mã pythonic sau đây không?Kiểm tra xem chuỗi có kết thúc bằng một trong các chuỗi từ danh sách

extensions = ['.mp3','.avi'] 
file_name = 'test.mp3' 

for extension in extensions: 
    if file_name.endswith(extension): 
     #do stuff 

Tôi có một ký ức mơ hồ rằng việc kê khai rõ ràng của for vòng lặp có thể tránh được và được ghi trong điều kiện if. Điều này có đúng không?

+0

Mặc dù câu hỏi này được trả lời tốt, có lẽ tác giả ban đầu nghĩ về 'if any ((file_name.endswith (ext) cho ext trong phần mở rộng))'. – sapht

Trả lời

289

Mặc dù không biết đến rộng rãi, str.endswith cũng chấp nhận một tuple. Bạn không cần phải lặp lại.

>>> 'test.mp3'.endswith(('.mp3', '.avi')) 
True 
+3

bạn có biết tại sao nó sẽ không chấp nhận một danh sách nhưng có một bộ tuple không? chỉ tò mò – ilyail3

+0

@falsetru Liên kết trong câu trả lời không trả lời rõ ràng câu hỏi đó. Nó chỉ đề cập rằng nó * có thể * chấp nhận tuple, nhưng không phải lý do tại sao nó * không thể * chấp nhận danh sách. Vì chúng là cả hai trình tự, sự khác biệt duy nhất tôi có thể thấy là danh sách có thể thay đổi, trong khi các bộ dữ liệu là không thay đổi. Tôi có thể sai, nhưng tôi không thể thấy bất kỳ lý do nào khác tại sao điều đó được tuyên bố rõ ràng. – KymikoLoco

+0

Nếu bạn muốn kiểm tra xem chuỗi có kết thúc bằng một chữ cái hay không: 'chuỗi nhập; str.endswith (tuple (string.ascii_lowercase)) ' –

31

Chỉ cần sử dụng:

if file_name.endswith(tuple(extensions)): 
4

Đi một phần mở rộng từ các tập tin và xem nếu nó nằm trong tập các phần mở rộng:

>>> import os 
>>> extensions = set(['.mp3','.avi']) 
>>> file_name = 'test.mp3' 
>>> extension = os.path.splitext(file_name)[1] 
>>> extension in extensions 
True 

Sử dụng một bộ vì thời gian phức tạp để tra cứu trong bộ là O (1) (docs).

+8

Chỉ cần lưu ý khi bạn đề cập đến hiệu quả, đối với các bộ dữ liệu khá ngắn, '.endswith()' với một tuple tập trung sẽ nhanh hơn một tra cứu thiết lập –

+1

@JonClements điểm tốt như mọi khi, cảm ơn bạn! – alecxe

+0

@ JonClements Tôi nghĩ bạn cần một huy hiệu nhận xét đặc biệt của SO vàng để tạo ghi chú tuyệt vời về câu trả lời và câu hỏi :) – alecxe

0

Tôi có điều này:

def has_extension(filename, extension): 

    ext = "." + extension 
    if filename.endswith(ext): 
     return True 
    else: 
     return False 
+1

Bạn có nghĩa là 'return filename.endswith (ext)'? : P –

2

Có hai cách: biểu thức thông thường và chuỗi (str) phương pháp.

Phương pháp chuỗi thường nhanh hơn (~ 2x).

import re, timeit 
p = re.compile('.*(.mp3|.avi)$', re.IGNORECASE) 
file_name = 'test.mp3' 
print(bool(t.match(file_name)) 
%timeit bool(t.match(file_name) 

792 ns ± 1,83 ns mỗi vòng lặp (trung bình ± std. Dev. 7 chạy, 1000000 vòng mỗi)

file_name = 'test.mp3' 
extensions = ('.mp3','.avi') 
print(file_name.lower().endswith(extensions)) 
%timeit file_name.lower().endswith(extensions) 

274 ​​ns ± 4,22 ns mỗi vòng lặp (trung bình ± std dev.. của 7 lần chạy, 1000000 vòng lặp)

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