जांचें कि क्या स्ट्रिंग किसी सूची में से किसी एक तार के साथ समाप्त होती है


220

निम्नलिखित कोड लिखने का पायथोनिक तरीका क्या है?

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

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

मेरे पास एक अस्पष्ट स्मृति है कि forलूप की स्पष्ट घोषणा से बचा जा सकता है और ifस्थिति में लिखा जा सकता है । क्या ये सच है?


2
हालांकि इस सवाल का अच्छी तरह से उत्तर दिया गया है, शायद लेखक ने मूल रूप से सोचा था if any((file_name.endswith(ext) for ext in extensions))
sapht

जवाबों:


450

हालांकि व्यापक रूप से ज्ञात नहीं है, str.endwith भी एक tuple को स्वीकार करता है। आपको लूप करने की आवश्यकता नहीं है।

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

10
क्या आप जानते हैं कि यह एक सूची को स्वीकार क्यों नहीं करेगा लेकिन टपल करता है? सिर्फ जिज्ञासु
ilyail3

2
@falsetru उत्तर में लिंक स्पष्ट रूप से उस प्रश्न का उत्तर नहीं देता है। इसमें केवल उल्लेख किया गया है कि यह ट्यूपल्स को स्वीकार कर सकता है, लेकिन यह नहीं कि यह सूचियों को स्वीकार क्यों नहीं कर सकता । चूंकि वे दोनों सीक्वेंस हैं, केवल एक अंतर जो मैं संभावित रूप से देख सकता हूं, वह यह है कि सूचियाँ परस्पर हैं, जबकि ट्यूप्स अपरिवर्तनीय हैं। मैं गलत हो सकता हूं, लेकिन मैं कोई अन्य कारण नहीं देख सकता कि क्यों स्पष्ट रूप से कहा गया है।
किमिकालोको

4
यदि आप जांचना चाहते हैं कि क्या एक पत्र के साथ एक स्ट्रिंग समाप्त होती है:import string; str.endswith(tuple(string.ascii_lowercase))
एलेक्स विलीसन

3
सिर्फ एक नोट, endswithकेवल अजगर 2.5 और इसके बाद के संस्करण के लिए tuple स्वीकार करता है
आकाश सिंह

1
यह कभी नहीं पता था! यह बिल्कुल सही है!
fool4jesus


6

फ़ाइल से एक्सटेंशन लें और देखें कि क्या वह एक्सटेंशन के सेट में है:

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

सेट का उपयोग करना क्योंकि सेट में लुकअप के लिए समय जटिलता O (1) ( डॉक्स ) है।


8
बस ध्यान दें करने के लिए आप दक्षता का उल्लेख के रूप में, काफी कम tuples के लिए, .endswith()एक प्रशिक्षु टपल साथ तेजी से एक सेट देखने से हो जाएगा
जॉन क्लेमेंट्स

@ जोंकल्स मुझे लगता है कि आपको उत्तर और प्रश्नों पर भयानक नोट्स बनाने के लिए एक विशेष SO गोल्ड कमेंट बैज की आवश्यकता है :)
alecxe

); - नहीं मैं तो बस "alecxe स्टॉकिंग" बिल्ला के लिए जा रहा हूँ
जॉन क्लेमेंट्स

2
यह भी ध्यान दें कि 2.7 और नए में, आप सेट के लिए गणित सिंटैक्स हमें दे सकते हैं {'.mp3','.avi'}, यह अतिरिक्त प्रकार के रूपांतरण से बचा जाता है और आपकी पृष्ठभूमि के आधार पर अधिक पठनीय हो सकता है ('हालांकि यह शब्दकोशों के साथ भ्रम पैदा कर सकता है, और खाली बनाने के लिए उपयोग नहीं किया जा सकता है) सेट)।
पर्किन्स

@JonClements किसी दिन मैं आप के रूप में बुद्धिमान हो जाएगा :)
alecxe

3

दो तरीके हैं: नियमित अभिव्यक्ति और स्ट्रिंग (स्ट्रै) तरीके।

स्ट्रिंग विधियां आमतौर पर तेज होती हैं (~ 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 एनएस 2 1.83 एनएस प्रति लूप (मतलब dev एसटीडी। 7 रन का देव, प्रत्येक 1000000 लूप)

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

274 ns 2 4.22 ns प्रति लूप (मतलब। Std। 7 रन की देव, 1000000 लूप प्रत्येक)



1

मैं अभी इस पार आया था, जबकि कुछ और तलाश कर रहा था।

मैं osपैकेज में तरीकों के साथ जाने की सलाह दूंगा। ऐसा इसलिए है क्योंकि आप इसे और अधिक सामान्य बना सकते हैं, किसी भी अजीब मामले की भरपाई कर सकते हैं।

आप कुछ ऐसा कर सकते हैं:

import os

the_file = 'aaaa/bbbb/ccc.ddd'

extensions_list = ['ddd', 'eee', 'fff']

if os.path.splitext(the_file)[-1] in extensions_list:
    # Do your thing.

0

एक और संभावना में बयान का उपयोग करने के लिए हो सकता है:

extensions = ['.mp3','.avi']
file_name  = 'test.mp3'
if "." in file_name and file_name[file_name.rindex("."):] in extensions:
    print(True)

@ रेनल्ड 62, उस मामले में indexहोना चाहिए rindex
नेवरलेस जूल

0

एक और तरीका है जो मिलान स्ट्रिंग की सूची वापस कर सकता है

sample = "alexis has the control"
matched_strings = filter(sample.endswith, ["trol", "ol", "troll"])
print matched_strings
['trol', 'ol']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.