Yanıtlar:
in
Operatörü kullanabilirsiniz :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
operatörü Rabin-Carp algoritmasını kullanıyor mu?
Bu yalnızca bir alt dize aramasıysa kullanabilirsiniz string.find("substring")
.
Sen biraz dikkatli olmak gerekiyor find
, index
ve in
onlar aramalar alt dize gibi olsa. Başka bir deyişle, bu:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Bu yazdıracak Found 'is' in the string.
, Benzer if "is" in s:
etmek değerlendirirsiniz True
. İstediğiniz şey bu olabilir veya olmayabilir.
if ' is ' in s:
geri dönecektir False
.
\bis\b
(kelime sınırları) olurdu .
' is '
, özellikle yakalanmayacaktır This is, a comma'
veya 'It is.'
.
s.split(string.punctuation + string.whitespace)
kez bile bölünecek şüpheliyim ; / / fonksiyon ailesi split
gibi değil , sadece tüm sınırlayıcı karakterleri bitişik olarak bu sırayla gördüğünde böler. Karakter sınıflarına bölmek istiyorsanız, düzenli ifadelere geri dönersiniz (hangi noktada, bölmeden arama yapmak daha basit ve daha hızlı bir yoldur). 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()
- tamam, puan alındı. Bu çok saçma ...
Python'un alt dize yöntemi içeren bir dizesi var mı?
Evet, ancak Python'un bunun yerine kullanmanız gereken bir karşılaştırma operatörü vardır, çünkü dil kullanımını amaçlamaktadır ve diğer programcılar bunu kullanmanızı bekler. in
Bir karşılaştırma operatörü olarak kullanılan bu anahtar kelime :
>>> 'foo' in '**foo**'
True
Orijinal sorunun sorduğu tam tersi (tamamlayıcı) not in
:
>>> 'foo' not in '**foo**' # returns False
False
Bu semantik olarak aynıdır, not 'foo' in '**foo**'
ancak daha okunabilir ve açıkça okunabilirlik iyileştirmesi olarak dilde sağlanmıştır.
__contains__
, find
veindex
Söz verildiği gibi, burada contains
yöntem:
str.__contains__('**foo**', 'foo')
döner True
. Bu işlevi süper sicim örneğinden de çağırabilirsiniz:
'**foo**'.__contains__('foo')
Ama yapma. Alt çizgilerle başlayan yöntemler semantik olarak özel kabul edilir. Bunu kullanmanın tek nedeni in
ve not in
işlevlerini genişletirken (örn. Alt sınıflama 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')
ve şimdi:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Ayrıca, aşağıdaki dize yöntemlerinden kaçının:
>>> '**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
Diğer dillerin doğrudan alt dizeleri test etmek için bir yöntemi olmayabilir ve bu nedenle bu tür yöntemleri kullanmanız gerekir, ancak Python ile in
karşılaştırma işlecini kullanmak çok daha etkilidir .
Aynı hedefe ulaşmanın çeşitli yollarını karşılaştırabiliriz.
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'))),
}
Ve şimdi kullanmanın in
diğerlerinden çok daha hızlı olduğunu görüyoruz . Eşdeğer bir işlem yapmak için daha az zaman daha iyidir:
>>> 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
ve str.find
? Başka birinin bir alt dizenin dizinini yalnızca var olup olmamasından ziyade bulmasını nasıl önerirsiniz? (veya bunları içerdikleri yerde kullanmaktan kaçınmayı mı kastediyordunuz - bu yüzden s.find(ss) != -1
bunun yerine kullanmayın ss in s
?)
re
modülün zarif kullanımı ile daha iyi ele alınabilir . Henüz yazdığım herhangi bir kodda str.index veya str.find için bir kullanım bulamadım.
str.count
( string.count(something) != 0
). titreme
operator
Modül sürümü nasıl çalışır ?
in_
yukarıdakiyle aynıdır - ancak etrafında bir yığın çerçevesiyle, bundan daha yavaştır: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:
@Michael'in dediği gibi normal kullanımdır - in
operatöre, bir yöntem çağrısından daha okunabilir ve daha hızlı dayanır .
Bir operatör yerine gerçekten bir yönteme ihtiyacınız varsa (örneğin, key=
çok tuhaf bir tür için biraz garip yapmak ...?), Bu olurdu 'haystack'.__contains__
. Ancak örneğiniz bir kullanımda olduğundan if
, sanırım ;-) demek istediğinizi gerçekten kastetmiyorsunuz. Özel yöntemleri doğrudan kullanmak iyi bir form değildir (ne okunabilir ne de verimli) - bunun yerine, onlara delege olan operatörler ve yerleşikler aracılığıyla kullanılması amaçlanmıştır.
in
Python dizeleri ve listeleriİşte in
yöntem hakkında kendileri için konuşan birkaç yararlı örnek :
"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]
Uyarı. Listeler yinelenebilirdir ve in
yöntem yalnızca dizgilere değil yinelemelere de uygulanır.
["bar", "foo", "foobar"] in "foof"
?
Memnun kalırsanız "blah" in somestring
ancak bir işlev / yöntem çağrısı olmasını istiyorsanız, muhtemelen bunu yapabilirsiniz
import operator
if not operator.contains(somestring, "blah"):
continue
Python Tüm operatörler az ya da çok bulunabilir olabilir operatör modülü dahil in
.
Görünüşe göre vektörel karşılaştırma için benzer bir şey yok. Bunu yapmanın bariz bir Python yolu:
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
Listelerle birlikte kullanılmaması gereken hiçbir şeye değmez , çünkü elementlerin doğrusal bir taramasını yapar ve karşılaştırıldığında yavaştır. Bunun yerine, özellikle üyelik testleri tekrar tekrar yapılacaksa bir set kullanın.
Kullanabilirsiniz y.count()
.
Bir alt dizenin bir dizede kaç kez göründüğünün tamsayı değerini döndürür.
Örneğin:
string.count("bah") >> 0
string.count("Hello") >> 1
İşte cevabınız:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Yanlış olup olmadığını kontrol etmek için:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
VEYA:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item)
,__iter__(self)
ve__getitem__(self, key)
belirli bir bir öğe yatıyor içerip içermediğini belirlemek için bu sırayla.in
Özel türünüze sunmak için bu yöntemlerden en az birini uygulayın .