ฉันกำลังมองหาstring.containsหรือstring.indexofวิธีการในหลาม
ฉันต้องการทำ:
if not somestring.contains("blah"):
continue
ฉันกำลังมองหาstring.containsหรือstring.indexofวิธีการในหลาม
ฉันต้องการทำ:
if not somestring.contains("blah"):
continue
คำตอบ:
คุณสามารถใช้inโอเปอเรเตอร์ :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
inดำเนินการPython ใช้อัลกอริทึม Rabin-Carp หรือไม่
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นี่อาจเป็นหรือไม่ใช่สิ่งที่คุณต้องการ
if ' is ' in s:สิ่งที่จะกลับมาFalseตามที่คาดไว้
\bis\b(ขอบเขตคำ)
' is 'สะดุดตาก็จะไม่จับหรือThis is, a comma' 'It is.'
s.split(string.punctuation + string.whitespace)ใดจะแยกแม้แต่ครั้งเดียว splitไม่เหมือนstrip/ rstrip/ lstripครอบครัวของฟังก์ชั่นก็แยกเมื่อเห็นตัวละครทุกตัวคั่นที่ติดกันในลำดับที่แน่นอน หากคุณต้องการแยกคลาสของตัวละครออกไปคุณจะกลับไปสู่นิพจน์ทั่วไป (ณ จุดนี้การค้นหาr'\bis\b'โดยไม่แยกเป็นวิธีที่ง่ายกว่าและเร็วกว่า)
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()- ตกลงจุดได้แล้ว นี่คือตอนนี้ไร้สาระ ...
Python มีสตริงที่มีวิธีย่อยหรือไม่?
ใช่ แต่ Python มีโอเปอเรเตอร์การเปรียบเทียบที่คุณควรใช้แทนเนื่องจากภาษานั้นตั้งใจจะใช้งานและโปรแกรมเมอร์คนอื่น ๆ ก็คาดหวังให้คุณใช้มัน คำหลักนั้นคือ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ผลตอบแทน คุณสามารถเรียกใช้ฟังก์ชันนี้ได้จากอินสแตนซ์ของ superstring:
'**foo**'.__contains__('foo')
แต่ทำไม่ได้ วิธีการที่ขึ้นต้นด้วยเครื่องหมายขีดล่างถือว่าเป็นความหมายแบบส่วนตัว เหตุผลเดียวที่จะใช้สิ่งนี้คือเมื่อขยายinและnot inฟังก์ชั่น (เช่นถ้า subclassing 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
ภาษาอื่นอาจไม่มีวิธีทดสอบโดยตรงสำหรับวัสดุพิมพ์ดังนั้นคุณจะต้องใช้วิธีการประเภทนี้ แต่ด้วย Python จะมีประสิทธิภาพมากกว่าในการใช้ตัว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}
str.indexและstr.find? คุณจะแนะนำคนอื่นให้ค้นหาดัชนีของสตริงย่อยแทนที่จะเป็นว่ามีอยู่หรือไม่? (หรือคุณหมายถึงหลีกเลี่ยงการใช้แทนการมี - ดังนั้นอย่าใช้s.find(ss) != -1แทนss in s?)
reโมดูลอย่างสง่างาม ฉันยังไม่พบการใช้งานสำหรับ str.index หรือ str.find ตัวเองในรหัสใด ๆ ที่ฉันได้เขียนเลย
str.countเช่นกัน ( string.count(something) != 0) ตัวสั่น
operatorรุ่นโมดูลดำเนินการ?
in_ข้างบน - แต่ด้วย stackframe รอบ ๆ ดังนั้นจึงช้ากว่านั้น: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:เป็นการใช้งานปกติตามที่ @Michael พูดว่า - มันขึ้นอยู่กับinโอเปอเรเตอร์อ่านได้ง่ายและเร็วกว่าการเรียกเมธอด
หากคุณต้องการวิธีการอย่างแท้จริงแทนที่จะเป็นโอเปอเรเตอร์ (เช่นทำอะไรแปลก ๆkey=สำหรับการจัดเรียงที่แปลกประหลาด ... ?) นั่นก็'haystack'.__contains__คือ แต่เนื่องจากตัวอย่างของคุณมีไว้สำหรับใช้ในifฉันเดาว่าคุณไม่ได้หมายถึงสิ่งที่คุณพูดจริงๆ ;-) มันไม่ใช่รูปแบบที่ดี (หรืออ่านได้หรือไม่มีประสิทธิภาพ) ในการใช้วิธีการพิเศษโดยตรง - พวกเขาตั้งใจจะใช้แทนผ่านโอเปอเรเตอร์และบิวด์อินที่มอบให้พวกเขาแทน
in Python สตริงและรายการนี่คือตัวอย่างที่เป็นประโยชน์ที่พูดถึงตัวเองเกี่ยวกับ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]
ข้อแม้. รายการเป็นแบบ iterables และinวิธีการทำงานกับ iterables ไม่ใช่แค่สตริง
["bar", "foo", "foobar"] in "foof"?
หากคุณมีความสุข"blah" in somestringแต่อยากให้มันเป็นการเรียกฟังก์ชั่น / เมธอดคุณอาจทำได้
import operator
if not operator.contains(somestring, "blah"):
continue
ผู้ประกอบการทั้งหมดในหลามได้มากขึ้นหรือน้อยกว่าที่พบในโมดูลผู้ประกอบการinรวมทั้ง
เห็นได้ชัดว่าไม่มีอะไรคล้ายกันสำหรับการเปรียบเทียบเวกเตอร์ที่ชาญฉลาด วิธีที่ชัดเจนของงูหลามคือ:
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
inไม่ควรใช้กับรายการเพราะเป็นการสแกนเชิงเส้นขององค์ประกอบและทำการเปรียบเทียบช้า ใช้ชุดอุปกรณ์แทนโดยเฉพาะถ้าการทดสอบความเป็นสมาชิกนั้นจะทำซ้ำ ๆ
y.count()คุณสามารถใช้
มันจะคืนค่าจำนวนเต็มของจำนวนครั้งที่สตริงย่อยปรากฏในสตริง
ตัวอย่างเช่น:
string.count("bah") >> 0
string.count("Hello") >> 1
นี่คือคำตอบของคุณ:
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
คุณสามารถใช้นิพจน์ทั่วไปเพื่อรับสิ่งที่เกิดขึ้น:
>>> import re
>>> print(re.findall(r'( |t)', to_search_in)) # searches for t or space
['t', ' ', 't', ' ', ' ']
__contains__(self, item),__iter__(self)และ__getitem__(self, key)อยู่ในลำดับที่เพื่อตรวจสอบว่ารายการโกหกในที่กำหนดให้มี ใช้วิธีการเหล่านี้อย่างน้อยหนึ่งวิธีเพื่อให้inสามารถใช้ได้กับประเภทที่คุณกำหนดเอง