Jawaban:
Anda dapat menggunakan in
operator :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
operator Python menggunakan algoritma Rabin-Carp?
Jika itu hanya pencarian substring yang dapat Anda gunakan string.find("substring")
.
Anda harus sedikit berhati-hati dengan find
, index
, dan in
meskipun, seperti yang substring pencarian. Dengan kata lain, ini:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Itu akan mencetak sama Found 'is' in the string.
, if "is" in s:
akan mengevaluasi True
. Ini mungkin atau mungkin bukan yang Anda inginkan.
if ' is ' in s:
yang akan kembali False
seperti yang diharapkan (mungkin).
\bis\b
(batas kata).
' is '
, terutama, itu tidak akan menangkap This is, a comma'
atau 'It is.'
.
s.split(string.punctuation + string.whitespace)
akan membagi bahkan sekali; split
tidak seperti strip
/ rstrip
/ lstrip
keluarga fungsi, itu hanya membagi ketika melihat semua karakter pembatas, contiguously, dalam urutan yang tepat. Jika Anda ingin membagi pada kelas karakter, Anda kembali ke ekspresi reguler (pada titik itu, mencari r'\bis\b'
tanpa pemisahan adalah cara yang lebih sederhana, lebih cepat untuk pergi).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()
- ok, poin diambil. Ini sekarang konyol ...
Apakah Python memiliki string yang berisi metode substring?
Ya, tetapi Python memiliki operator pembanding yang harus Anda gunakan sebagai gantinya, karena bahasa tersebut bermaksud penggunaannya, dan programmer lain akan mengharapkan Anda untuk menggunakannya. Kata kunci itu in
, yang digunakan sebagai operator perbandingan:
>>> 'foo' in '**foo**'
True
Sebaliknya (komplemen), yang ditanyakan oleh pertanyaan asli, adalah not in
:
>>> 'foo' not in '**foo**' # returns False
False
Ini semantik sama dengan not 'foo' in '**foo**'
tetapi jauh lebih mudah dibaca dan secara eksplisit disediakan dalam bahasa sebagai peningkatan keterbacaan.
__contains__
, find
danindex
Seperti yang dijanjikan, inilah contains
caranya:
str.__contains__('**foo**', 'foo')
kembali True
. Anda juga dapat memanggil fungsi ini dari instance superstring:
'**foo**'.__contains__('foo')
Tapi jangan. Metode yang dimulai dengan garis bawah dianggap semantik pribadi. Satu-satunya alasan untuk menggunakan ini adalah ketika memperluas in
dan not in
fungsionalitas (mis. Jika 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')
dan sekarang:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Selain itu, hindari metode string berikut:
>>> '**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
Bahasa lain mungkin tidak memiliki metode untuk menguji langsung untuk substring, dan Anda harus menggunakan jenis metode ini, tetapi dengan Python, jauh lebih efisien untuk menggunakan in
operator pembanding.
Kita dapat membandingkan berbagai cara untuk mencapai tujuan yang sama.
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'))),
}
Dan sekarang kita melihat bahwa menggunakan in
jauh lebih cepat daripada yang lain. Lebih sedikit waktu untuk melakukan operasi yang setara lebih baik:
>>> 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
dan str.find
? Bagaimana lagi Anda menyarankan seseorang menemukan indeks substring alih-alih hanya apakah itu ada atau tidak? (Atau maksud Anda menghindari menggunakannya di tempat mengandung - jadi jangan gunakan s.find(ss) != -1
bukan ss in s
?)
re
modul yang elegan . Saya belum menemukan penggunaan untuk str.index atau str.find sendiri dalam kode apa pun yang saya tulis.
str.count
juga ( string.count(something) != 0
). gemetar
operator
versi modul ?
in_
atas - tetapi dengan susunan bingkai di sekitarnya, jadi lebih lambat dari itu: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:
adalah penggunaan normal, seperti yang dikatakan @Michael - ini bergantung pada in
operator, lebih mudah dibaca dan lebih cepat daripada pemanggilan metode.
Jika Anda benar-benar membutuhkan metode alih-alih operator (mis. Untuk melakukan sesuatu yang aneh key=
untuk jenis yang sangat aneh ...?), Itu mungkin 'haystack'.__contains__
. Tapi karena contoh Anda adalah untuk digunakan dalam if
, saya kira Anda tidak benar-benar bermaksud apa yang Anda katakan ;-). Ini bukan bentuk yang baik (atau dapat dibaca, atau efisien) untuk menggunakan metode khusus secara langsung - mereka seharusnya digunakan, sebagai gantinya, melalui operator dan builtin yang mendelegasikan kepada mereka.
in
String dan daftar PythonBerikut adalah beberapa contoh berguna yang berbicara sendiri tentang in
metode ini:
"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]
Peringatan. Daftar adalah iterables, dan in
metode ini bekerja pada iterables, bukan hanya string.
["bar", "foo", "foobar"] in "foof"
?
Jika Anda senang "blah" in somestring
tetapi menginginkannya menjadi panggilan fungsi / metode, Anda mungkin dapat melakukan ini
import operator
if not operator.contains(somestring, "blah"):
continue
Semua operator di Python dapat lebih atau kurang ditemukan dalam modul operator termasuk in
.
Jadi rupanya tidak ada yang serupa untuk perbandingan bijaksana. Cara Python yang jelas untuk melakukannya adalah:
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
tidak boleh digunakan dengan daftar karena melakukan pemindaian linear elemen dan lambat dibandingkan. Gunakan set sebagai gantinya, terutama jika tes keanggotaan harus dilakukan berulang kali.
Anda bisa menggunakannya y.count()
.
Ini akan mengembalikan nilai integer dari berapa kali sebuah sub string muncul dalam sebuah string.
Sebagai contoh:
string.count("bah") >> 0
string.count("Hello") >> 1
Inilah jawaban Anda:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Untuk memeriksa apakah itu salah:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
ATAU:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item)
,,__iter__(self)
dan__getitem__(self, key)
dalam urutan itu untuk menentukan apakah suatu item terletak pada suatu konten. Terapkan setidaknya satu dari metode itu untuk membuatin
tersedia untuk jenis kustom Anda.