क्या पायथन में एक स्ट्रिंग है जिसमें 'प्रतिस्थापन विधि है?


3599

मैं पायथन में एक विधि string.containsया string.indexofविधि की तलाश कर रहा हूं ।

मैं करना चाहता हूँ:

if not somestring.contains("blah"):
   continue

जवाबों:


6256

आप inऑपरेटर का उपयोग कर सकते हैं :

if "blah" not in somestring: 
    continue

229
हुड के अंतर्गत, अजगर का उपयोग करेगा __contains__(self, item), __iter__(self)और __getitem__(self, key)है कि यह निर्धारित करने के एक दिया में एक आइटम झूठ होता है कि क्या में। inअपने कस्टम प्रकार को उपलब्ध कराने के लिए उन तरीकों में से कम से कम एक को लागू करें।
बॉलपॉइंटबैन

27
बस सुनिश्चित करें कि somestring कोई नहीं होगा। अन्यथा आप एकTypeError: argument of type 'NoneType' is not iterable
बिग कद्दू

5
एफडब्ल्यूआईडब्ल्यू, यह उक्त लक्ष्य को पूरा करने का एक आदर्श तरीका है।
ट्रेंटन

6
स्ट्रिंग्स के लिए, पायथन inऑपरेटर राबिन-कार्प एल्गोरिथ्म का उपयोग करता है?
सैम चैट्स

3
@SamChat कार्यान्वयन विवरण के लिए (CPython में; afaik भाषा विनिर्देश यहाँ कोई विशेष एल्गोरिथ्म जनादेश नहीं है) stackoverflow.com/questions/18139660/… देखें ।
क्रिस्टोफ़ बुर्शका

667

यदि यह सिर्फ एक विकल्प खोज है जिसका आप उपयोग कर सकते हैं string.find("substring")

आप के साथ एक छोटे से सावधान रहने की क्या ज़रूरत है find, indexऔर inहै, हालांकि के रूप में वे खोज सबस्ट्रिंग कर रहे हैं। दूसरे शब्दों में, यह:

s = "This be a string"
if s.find("is") == -1:
    print("No 'is' here!")
else:
    print("Found 'is' in the string.")

यह Found 'is' in the string.इसी तरह छपेगा, if "is" in s:मूल्यांकन करेगा True। यह वही हो सकता है या नहीं हो सकता है जो आप चाहते हैं।


78
सबटैक सर्चिंग में शामिल गोचरों को हाइलाइट करने के लिए। स्पष्ट समाधान वह है if ' is ' in s:जो उम्मीद के मुताबिक False(शायद) वापस आ जाएगा ।
एरोनस्टरलिंग

94
@aronasterling स्पष्ट रूप से यह हो सकता है, लेकिन पूरी तरह से सही नहीं है। क्या होगा यदि आपके पास विराम चिह्न है या यह शुरुआत या अंत में है? पूंजीकरण के बारे में क्या? बेहतर \bis\b( केस सीमाओं) के लिए असंवेदनशील रेगेक्स खोज एक मामला होगा ।
बॉब

2
@ जैमीबुल एक बार फिर, आपको इस बात पर विचार करना चाहिए कि क्या आप शब्द के लिए परिसीमन के रूप में विराम चिह्न को शामिल करना चाहते हैं। बंटवारे का काफी हद तक एक ही प्रभाव होगा कि जाँच के भोले समाधान के लिए ' is ', विशेष रूप से, यह पकड़ This is, a comma'या नहीं होगा 'It is.'
बॉब

7
@ जैमीबुल: मुझे अत्यधिक संदेह है कि किसी भी वास्तविक इनपुट के साथ s.split(string.punctuation + string.whitespace)विभाजन एक बार भी हो जाएगा; / / फ़ंक्शंस के परिवार की splitतरह नहीं है , यह केवल तभी विभाजित होता है जब यह सभी सीमांत वर्णों को देखता है, संयोग से, उस सटीक क्रम में। यदि आप चरित्र वर्गों पर विभाजित करना चाहते हैं, तो आप नियमित अभिव्यक्तियों पर वापस आ जाते हैं (जिस बिंदु पर, विभाजन के बिना खोजना सरल, तेज रास्ता तय करना है)। striprstriplstripr'\bis\b'
शैडो रेंजर

8
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()- ठीक है, बिंदु लिया गया। यह अब हास्यास्पद है ...
जेमी बुल 11

190

क्या पायथन में स्ट्रिंग है जिसमें प्रतिस्थापन विधि है?

हां, लेकिन पायथन के पास एक तुलना ऑपरेटर है जिसे आपको इसके बजाय उपयोग करना चाहिए, क्योंकि भाषा इसका उपयोग करना चाहती है, और अन्य प्रोग्रामर आपसे इसका उपयोग करने की उम्मीद करेंगे। वह कीवर्ड है in, जिसका उपयोग तुलना ऑपरेटर के रूप में किया जाता है:

>>> 'foo' in '**foo**'
True

विपरीत (पूरक), जो मूल प्रश्न पूछता है, वह है not in:

>>> 'foo' not in '**foo**' # returns False
False

यह शब्दार्थ के समान है not 'foo' in '**foo**'लेकिन यह पठनीयता में सुधार के रूप में भाषा के लिए बहुत अधिक पठनीय और स्पष्ट रूप से प्रदान किया गया है।

प्रयोग करने से बचें __contains__, findऔरindex

जैसा कि वादा किया गया था, यहाँ containsविधि है:

str.__contains__('**foo**', 'foo')

लौटता है True। आप इस फ़ंक्शन को सुपरस्ट्रिंग के उदाहरण से भी कॉल कर सकते हैं:

'**foo**'.__contains__('foo')

लेकिन नहीं। अंडरस्कोर से शुरू होने वाले तरीकों को शब्दार्थ रूप से निजी माना जाता है। इसका उपयोग करने का एकमात्र कारण यह है कि जब कार्यक्षमता inऔर not inकार्यक्षमता बढ़ रही हो (जैसे यदि उपवर्ग str):

class NoisyString(str):
    def __contains__(self, other):
        print('testing if "{0}" in "{1}"'.format(other, self))
        return super(NoisyString, self).__contains__(other)

ns = NoisyString('a string with a substring inside')

और अब:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

इसके अलावा, निम्नलिखित स्ट्रिंग विधियों से बचें:

>>> '**foo**'.index('foo')
2
>>> '**foo**'.find('foo')
2

>>> '**oo**'.find('foo')
-1
>>> '**oo**'.index('foo')

Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    '**oo**'.index('foo')
ValueError: substring not found

अन्य भाषाओं में सब्सट्रिंग के लिए सीधे परीक्षण करने की कोई विधि नहीं हो सकती है, और इसलिए आपको इन प्रकार के तरीकों का उपयोग करना होगा, लेकिन पायथन के साथ inतुलना ऑपरेटर का उपयोग करना अधिक कुशल है ।

प्रदर्शन की तुलना

हम एक ही लक्ष्य को पूरा करने के विभिन्न तरीकों की तुलना कर सकते हैं।

import timeit

def in_(s, other):
    return other in s

def contains(s, other):
    return s.__contains__(other)

def find(s, other):
    return s.find(other) != -1

def index(s, other):
    try:
        s.index(other)
    except ValueError:
        return False
    else:
        return True



perf_dict = {
'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
'__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
'__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}

और अब हम देखते हैं कि inदूसरों की तुलना में इसका उपयोग बहुत तेज है। समतुल्य ऑपरेशन करने के लिए कम समय बेहतर है:

>>> perf_dict
{'in:True': 0.16450627865128808,
 'in:False': 0.1609668098178645,
 '__contains__:True': 0.24355481654697542,
 '__contains__:False': 0.24382793854783813,
 'find:True': 0.3067379407923454,
 'find:False': 0.29860888058124146,
 'index:True': 0.29647137792585454,
 'index:False': 0.5502287584545229}

6
क्यों एक से बचना चाहिए str.indexऔर str.find? आप कैसे सुझाएंगे कि कोई व्यक्ति विकल्प के सूचकांक को खोजने के बजाय सिर्फ यह मौजूद है या नहीं? (या क्या आपका मतलब है कि उनमें शामिल होने के स्थान पर उपयोग करने से बचें - इसलिए s.find(ss) != -1इसके बजाय उपयोग न करें ss in s?)
कोडरफ़ॉर्फ़िन

3
संक्षेप में ऐसा है, हालांकि reमॉड्यूल के सुरुचिपूर्ण उपयोग से उन तरीकों के उपयोग के पीछे की मंशा को बेहतर ढंग से संबोधित किया जा सकता है । मुझे अभी तक str.index या str.find के लिए कोई उपयोग नहीं मिला है जो मैंने अभी तक किसी भी कोड में लिखा है।
हारून हॉल

कृपया अपने उत्तर का उपयोग करने के खिलाफ सलाह देने के लिए विस्तार करें str.count( string.count(something) != 0)। कंपकंपी
cs95

operatorमॉड्यूल संस्करण कैसे प्रदर्शन करता है?
jpmc26

@ jpmc26 यह in_ऊपर के समान ही है - लेकिन इसके चारों ओर एक स्टैकफ्रेम के साथ, इसलिए यह उससे धीमा है: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
एरॉन हॉल

175

if needle in haystack:@Michael कहते हैं - यह सामान्य उपयोग है, यह inऑपरेटर पर निर्भर करता है , एक विधि कॉल की तुलना में अधिक पठनीय और तेज है।

यदि आपको वास्तव में एक ऑपरेटर के बजाय एक विधि की आवश्यकता है (जैसे कि key=बहुत अजीब तरह के लिए कुछ अजीब करने के लिए ...?), तो यह होगा 'haystack'.__contains__। लेकिन जब से आपका उदाहरण एक में उपयोग के लिए है if, तो मुझे लगता है कि आप वास्तव में क्या मतलब नहीं है; ;-) सीधे तौर पर विशेष विधियों का उपयोग करने के लिए यह अच्छा रूप नहीं है (न ही पठनीय, और न ही कुशल) - उनका उपयोग करने के लिए किया जाता है, इसके बजाय, ऑपरेटरों और बिल्डरों के माध्यम से जो उन्हें सौंपते हैं।


55

in पायथन तार और सूची

यहाँ कुछ उपयोगी उदाहरण दिए गए हैं जो इस inविधि से संबंधित स्वयं के लिए बोलते हैं :

"foo" in "foobar"
True

"foo" in "Foobar"
False

"foo" in "Foobar".lower()
True

"foo".capitalize() in "Foobar"
True

"foo" in ["bar", "foo", "foobar"]
True

"foo" in ["fo", "o", "foobar"]
False

["foo" in a for a in ["fo", "o", "foobar"]]
[False, False, True]

चेतावनी। सूची पुनरावृत्तियाँ हैं, और inविधि पुनरावृत्तियों पर कार्य करती है, न कि केवल तार पर।


1
क्या सूची को किसी स्ट्रिंग में सूची में से किसी में देखने के लिए चारों ओर घुमाया जा सकता है? उदाहरण के लिए: ["bar", "foo", "foobar"] in "foof"?
कैफिनेटेड कोडर

1
@CaffeinatedCoder, नहीं, इसके लिए नेस्टेड पुनरावृत्ति की आवश्यकता होती है। पाइप के साथ सूची में शामिल होने से सबसे अच्छा "" .join (["बार", "फू", "फोब्बर"]) और इसमें से एक
रेगीक्स

2
कोई भी ([["बार" में x के लिए "फूफ़" में x, "फू", "फ़ोबार"]])
इजाक वीस

1
@IzaakWeiss आपका एक लाइनर काम करता है, लेकिन यह बहुत पठनीय नहीं है, और यह नेस्टेड पुनरावृत्ति करता है। मैं ऐसा करने के खिलाफ सलाह
दूंगा

1
@ PiyushS.Wanare आप जटिलता से क्या मतलब है? "डब्ल्यूटीएफ / मिनट" रेगेक्स के साथ बहुत अधिक है।
फायरलैक्स

42

अगर आप इससे खुश हैं "blah" in somestringलेकिन चाहते हैं कि यह एक फंक्शन / मेथड कॉल हो, तो आप शायद ऐसा कर सकते हैं

import operator

if not operator.contains(somestring, "blah"):
    continue

पायथन में सभी ऑपरेटर ऑपरेटर मॉड्यूल सहित कम या ज्यादा पाए जा सकते हैं in


40

तो जाहिर है कि वेक्टर-वार तुलना के लिए कुछ भी समान नहीं है। ऐसा करने का एक स्पष्ट पायथन तरीका होगा:

names = ['bob', 'john', 'mike']
any(st in 'bob and john' for st in names) 
>> True

any(st in 'mary and jane' for st in names) 
>> False

1
ऐसा इसलिए है क्योंकि परमाणु चर से उत्पाद बनाने का एक बड़ा तरीका है। आप उन्हें एक टपल में सूचीबद्ध कर सकते हैं, एक सूची (जो कार्टेशियन उत्पादों के रूप हैं और एक निहित आदेश के साथ आते हैं), या उन्हें एक वर्ग (कोई प्राथमिकता क्रम) या शब्दकोश मान के गुणों का नाम दिया जा सकता है, या वे फाइलों में हो सकते हैं एक निर्देशिका, या जो भी हो। जब भी आप विशिष्ट रूप से किसी 'कंटेनर' या 'संदर्भ' में कुछ (iter या getitem) की पहचान कर सकते हैं, तो आप उस 'कंटेनर' को एक प्रकार के वेक्टर के रूप में देख सकते हैं और उस पर द्विआधारी ऑप्स को परिभाषित कर सकते हैं। en.wikipedia.org/wiki/…
Niriel

वर्थ कुछ भी inनहीं जिसका उपयोग सूचियों के साथ नहीं किया जाना चाहिए क्योंकि यह तत्वों का एक रैखिक स्कैन करता है और इसकी तुलना धीमी है। इसके बजाय एक सेट का उपयोग करें, खासकर अगर सदस्यता परीक्षण बार-बार किया जाना है।
cs95 3

22

आप उपयोग कर सकते हैं y.count()

यह एक स्ट्रिंग में एक उप स्ट्रिंग प्रकट होने की संख्या के पूर्णांक मान को लौटाएगा।

उदाहरण के लिए:

string.count("bah") >> 0
string.count("Hello") >> 1

7
एक स्ट्रिंग गिनती जब तुम सिर्फ करना चाहते हैं महंगा है की जाँच करता है, तो यह नहीं है ...
जीन फ़्राँस्वा Fabre

3
वे विधियाँ जो मूल पद में 2010 से मौजूद हैं इसलिए मैंने उन्हें समुदाय से सर्वसम्मति के साथ संपादित करना समाप्त कर दिया (देखें मेटा पोस्ट meta.stackoverflow.com/questions/385063/… )
जीन-फ्रांकोइस

17
नहीं। मेरी बात "क्यों 9 साल पहले दूसरों के समान सटीक उत्तर देना" था?
जीन फ़्राँस्वा Fabre

10
क्योंकि मैं इस साइट को मॉडरेट कर रहा हूँ ... मैं मेटा पर प्रश्न पूछा गया है meta.stackoverflow.com/questions/385063/...
जीन फ़्राँस्वा Fabre

2
तब यदि आपके पास इसे हटाने का अधिकार है, तो इसे हटा दें, अन्यथा वही करें जो आपको करना चाहिए और आगे बढ़ना चाहिए। IMO यह उत्तर मान जोड़ता है, जो उपयोगकर्ताओं से अप-वोट द्वारा परिलक्षित होता है।
ब्रैंडन बैली

20

यहाँ आपका जवाब है:

if "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

जाँच के लिए कि क्या यह गलत है:

if not "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

या:

if "insert_char_or_string_here" not in "insert_string_to_search_here":
    #DOSTUFF

8

आप घटनाओं को प्राप्त करने के लिए नियमित अभिव्यक्ति का उपयोग कर सकते हैं:

>>> import re
>>> print(re.findall(r'( |t)', to_search_in)) # searches for t or space
['t', ' ', 't', ' ', ' ']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.