ฉันกำลังมองหา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
สามารถใช้ได้กับประเภทที่คุณกำหนดเอง