පයිතන්ට උපස්ථර ක්‍රමයක් 'අඩංගු' තිබේද?


3599

මම පයිතන්හි ක්‍රමයක් string.containsහෝ string.indexofක්‍රමයක් සොයමි .

මට කරන්න ඕනි:

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

Answers:


6278

ඔබට inක්රියාකරු භාවිතා කළ හැකිය :

if "blah" not in somestring: 
    continue

236
ඒ අවටනම් යටතේ, Python භාවිතා කරනු ඇත __contains__(self, item), __iter__(self)සහ __getitem__(self, key)දෙන ලද අයිතමයක් බොරු අඩංගු යන්න තීරණය කිරීම සඳහා ලබන පිණිසය. inඔබගේ අභිරුචි වර්ගයට ලබා දීම සඳහා අවම වශයෙන් එක් ක්‍රමයක් වත් ක්‍රියාත්මක කරන්න.
බෝල්පොයින්ට්බෙන්

28
කිසියම් දෙයක් නොවන බවට වග බලා ගන්න. එසේ නොමැතිනම් ඔබටTypeError: argument of type 'NoneType' is not iterable
ලොකු වට්ටක්කා

6
FWIW, මෙම ඉලක්කය සපුරා ගැනීම සඳහා මුග්ධ මාර්ගය මෙයයි.
ට්‍රෙන්ටන්

7
නූල් සඳහා, පයිතන් inක්‍රියාකරු රාබින්-කාප් ඇල්ගොරිතම භාවිතා කරයිද?
සෑම් චැට්ස්

4
ක්‍රියාත්මක කිරීමේ විස්තර සඳහා amSamChats stackoverflow.com/questions/18139660/… බලන්න ( CPython හි; භාෂා පිරිවිතර මෙහි විශේෂිත ඇල්ගොරිතමයක් නියම නොකරයි).
ක්‍රිස්ටෝෆ් බර්ෂ්කා

669

එය උපස්ථර සෙවුමක් නම් ඔබට භාවිතා කළ හැකිය string.find("substring").

ඔබ සමඟ ටිකක් පරිස්සම් විය යුතු නැහැ find, indexසහ inඔවුන් සෝදිසි substring ඇත ලෙස, නමුත්. වෙනත් වචන වලින් කිවහොත්, මෙය:

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. මෙය ඔබට අවශ්‍ය දේ හෝ නොවිය හැකිය.


79
උපස්ථර සෙවීම් වලට සම්බන්ධ ගොචා ඉස්මතු කිරීම සඳහා +1. පැහැදිලි විසඳුම වන්නේ (බොහෝ විට) අපේක්ෂා කළ ආකාරයටම if ' is ' in s:නැවත පැමිණීමයි False.
aaronasterling

96
@aaronasterling පැහැදිලිවම එය විය හැකි නමුත් සම්පූර්ණයෙන්ම නිවැරදි නොවේ. ඔබට විරාම ලකුණු තිබේ නම් හෝ එය ආරම්භයේ හෝ අවසානයේ තිබේ නම් කුමක් කළ යුතුද? ප්‍රාග්ධනීකරණය ගැන කුමක් කිව හැකිද? \bis\b(වචන මායිම්) සඳහා සංවේදී නොවන රීජෙක්ස් සෙවීම වඩා හොඳය .
බොබ්

2
Am ජේමිබුල් නැවත වරක්, වචනයක් සඳහා පරිසීමකයක් ලෙස විරාම ලකුණු ඇතුළත් කිරීමට අවශ්‍ය නම් ඔබ සලකා බැලිය යුතුය. පැලෙන සඳහා පරීක්ෂා කිරීම බොළඳ විසඳුමක් ලෙස බොහෝ දුරට එක සමාන බලපෑමක් ඇති වනු ඇත ' is ', විශේෂයෙන්, එය අල්ලා ගත නොහැකි වනු ඇත This is, a comma'හෝ 'It is.'.
බොබ්

7
Am ජේමිබුල්: ඕනෑම සැබෑ ආදාන බෙදීමක් 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()- හරි, ගත් කාරණය. මෙය දැන් හාස්‍යජනකය ...
ජේමි බුල්

194

පයිතන්හි නූලක් උපස්ථර ක්‍රමයක් තිබේද?

ඔව්, නමුත් පයිතන් සතුව ඔබ ඒ වෙනුවට භාවිතා කළ යුතු සංසන්දනාත්මක ක්‍රියාකරුවෙකු ඇත, මන්ද භාෂාව එහි භාවිතය අදහස් කරන අතර අනෙක් ක්‍රමලේඛකයින් ඔබ එය භාවිතා කරනු ඇතැයි අපේක්ෂා කරයි. එම මූල පදය 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')

නමුත් එපා. යටි ඉරි වලින් ආරම්භ වන ක්‍රම අර්ථකථන වශයෙන් පුද්ගලික ලෙස සැලකේ. මෙය භාවිතා කිරීමට ඇති එකම හේතුව වන්නේ ක්‍රියාකාරීත්වය දීර් ing කිරීමේදී 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?)
coderforlife

3
නිශ්චිතවම එසේ වුවද, reමොඩියුලය අලංකාර ලෙස භාවිතා කිරීමෙන් එම ක්‍රම භාවිතා කිරීමේ අභිප්‍රාය වඩා හොඳින් විසඳිය හැකිය . මම තවම ලියා ඇති කිසිදු කේතයක str.index හෝ str.find සඳහා භාවිතයක් සොයාගෙන නොමැත.
ආරොන් හෝල්

str.count( string.count(something) != 0) භාවිතා කිරීමට එරෙහි උපදෙස් සඳහා කරුණාකර ඔබේ පිළිතුර දිගු කරන්න . කම්පනයට
cs95


pm jpmc26 එය in_ඉහත ආකාරයටම වේ - නමුත් එය වටා සිරස් රාමුවක් ඇත, එබැවින් එය ඊට වඩා මන්දගාමී වේ: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
ආරොන් හෝල්

176

if needle in haystack:use මයිකල් පවසන පරිදි සාමාන්‍ය භාවිතය වේ - එය 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
A කැෆිනේටඩ් කෝඩර්, නැත, මේ සඳහා කැදැලි නැවත යෙදීම අවශ්‍ය වේ. හොඳම පයිප්ප සමග ලැයිස්තුව එක්වීමට විසින් සිදු "|" .join ([ "බාර්", "foo", "ෆූබාර්"]) සහ එය ක regex සිදු සම්පාදනය කිරීමට, පසුව "foof" මත ගැලපෙන
firelynx

2
ඕනෑම ([x හි "foof" හි x සඳහා ["තීරුව", "foo", "foobar"])
ඉසාක් වයිස්

1
ZIzaakWeiss ඔබේ එක් ලයිනර් ක්‍රියා කරයි, නමුත් එය එතරම් කියවිය නොහැකි අතර එය කූඩු පුනරාවර්තනය කරයි. මෙය කිරීමට එරෙහිව මම උපදෙස්
දෙමි

1
I PiyushS.Wanare සංකීර්ණතාවයෙන් ඔබ අදහස් කරන්නේ කුමක්ද? "WTF / min" රීජෙක්ස් සමඟ බොහෝ ඉහළ ය.
firelynx

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/…
නිරියෙල්

inලැයිස්තු සමඟ භාවිතා නොකළ යුතු කිසිවක් වටින්නේ නැත, මන්ද එය මූලද්‍රව්‍ය රේඛීය ස්කෑන් කිරීමක් හා සාපේක්ෂව මන්දගාමී වේ. ඒ වෙනුවට කට්ටලයක් භාවිතා කරන්න, විශේෂයෙන් සාමාජිකත්ව පරීක්ෂණ නැවත නැවත සිදු කිරීමට නම්.
cs95

22

ඔබට භාවිතා කළ හැකිය y.count().

එමඟින් නූලක් තුළ උප නූලක් දිස්වන වාර ගණනෙහි පූර්ණ සංඛ්‍යා අගය ලබා දෙනු ඇත.

උදාහරණයක් වශයෙන්:

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

8
ඔබට එය තිබේදැයි පරීක්ෂා කිරීමට අවශ්‍ය වූ විට නූලක් ගණන් කිරීම මිල
අධිකය

3
ක්රම මම ප්රජාවේ සම්මුතියක් සමග, ඔවුන් පිටතට සංස්කරණය අවසන් එසේ 2010 සිට මුල් පශ්චාත් පවතින (මෙටා පශ්චාත් බලන්න meta.stackoverflow.com/questions/385063/... )
ජීන් ප්රංශුවා Fabre

17
නොමැත. මගේ අදහස නම් "අවුරුදු 9 කට පෙර අනෙක් අය කළාක් මෙන් හරියටම පිළිතුරු දෙන්නේ ඇයි" යන්නයි.
ජීන්-ප්‍රංශුවා ෆැබ්‍රේ

10
මොකද මම වෙබ් අඩවිය නවීකරණය කරනවා
ජීන්-ප්‍රංශුවා

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', ' ', ' ']
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.