Yanıtlar:
inOperatörü kullanabilirsiniz :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
inoperatö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, indexve inonlar 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 splitgibi 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). striprstriplstripr'\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. inBir 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__, findveindexSöz verildiği gibi, burada containsyö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 inve not iniş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 inkarşı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 indiğ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.indexve 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) != -1bunun yerine kullanmayın ss in s?)
remodü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
operatorModü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 - inoperatö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 inyö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 inyöntem yalnızca dizgilere değil yinelemelere de uygulanır.
["bar", "foo", "foobar"] in "foof"?
Memnun kalırsanız "blah" in somestringancak 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
inListelerle 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 .