Réponses:
Vous pouvez utiliser l' inopérateur :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
inopérateur Python utilise-t-il l'algorithme Rabin-Carp?
Si c'est juste une recherche de sous-chaîne que vous pouvez utiliser string.find("substring").
Vous ne devez être un peu prudent avec find, indexet insi, comme ils sont sousChaîne recherches. En d'autres termes, ceci:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Il imprimerait de la Found 'is' in the string.même manière, if "is" in s:évaluerait True. Cela peut ou non être ce que vous voulez.
if ' is ' in s:qui reviendra Falsecomme prévu (probablement).
\bis\b(limites de mots).
' is ', notamment, il n'attrapera pas This is, a comma'ou 'It is.'.
s.split(string.punctuation + string.whitespace)se divise même une fois; splitn'est pas comme la famille de fonctions strip/ rstrip/ lstrip, elle ne se divise que lorsqu'elle voit tous les caractères délimiteurs, contigus, dans cet ordre exact. Si vous souhaitez diviser les classes de caractères, vous revenez aux expressions régulières (à quel moment, rechercher r'\bis\b'sans fractionner est le moyen le plus simple et le plus rapide).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()- ok, remarque prise. C'est maintenant ridicule ...
Python a-t-il une chaîne contenant une méthode de sous-chaîne?
Oui, mais Python a un opérateur de comparaison que vous devez utiliser à la place, car le langage a l'intention de l'utiliser, et d'autres programmeurs s'attendront à ce que vous l'utilisiez. Ce mot-clé est inutilisé comme opérateur de comparaison:
>>> 'foo' in '**foo**'
True
Le contraire (complément), que la question initiale demande, est not in:
>>> 'foo' not in '**foo**' # returns False
False
C'est sémantiquement le même que not 'foo' in '**foo**'mais c'est beaucoup plus lisible et explicitement prévu dans le langage comme une amélioration de la lisibilité.
__contains__, findetindexComme promis, voici la containsméthode:
str.__contains__('**foo**', 'foo')
retourne True. Vous pouvez également appeler cette fonction à partir de l'instance de la super chaîne:
'**foo**'.__contains__('foo')
Mais non. Les méthodes commençant par des traits de soulignement sont considérées comme sémantiquement privées. La seule raison d'utiliser cela est lors de l'extension des fonctionnalités inet not in(par exemple, si le sous-classement 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')
et maintenant:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Évitez également les méthodes de chaîne suivantes:
>>> '**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
D'autres langages peuvent ne pas avoir de méthodes pour tester directement les sous-chaînes, et vous devrez donc utiliser ces types de méthodes, mais avec Python, il est beaucoup plus efficace d'utiliser l' inopérateur de comparaison.
Nous pouvons comparer différentes façons d'atteindre le même objectif.
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'))),
}
Et maintenant, nous voyons que l'utilisation inest beaucoup plus rapide que les autres. Moins de temps pour faire une opération équivalente, c'est mieux:
>>> 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.indexet str.find? Sinon, comment suggéreriez-vous que quelqu'un trouve l'index d'une sous-chaîne au lieu de simplement savoir s'il existe ou non? (ou avez - vous évité moyen de les utiliser à la place de contient - alors ne pas utiliser au s.find(ss) != -1lieu de ss in s?)
remodule. Je n'ai pas encore trouvé d'utilisation pour str.index ou str.find moi-même dans aucun code que j'ai écrit pour le moment.
str.count( string.count(something) != 0). frisson
operatorversion du module ?
in_ci-dessus - mais avec un stackframe autour, donc c'est plus lent que ça: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:est l'utilisation normale, comme le dit @Michael - elle repose sur l' inopérateur, plus lisible et plus rapide qu'un appel de méthode.
Si vous avez vraiment besoin d'une méthode au lieu d'un opérateur (par exemple, pour faire un peu bizarre key=pour un type très particulier ...?), Ce serait 'haystack'.__contains__. Mais comme votre exemple est destiné à être utilisé dans un if, je suppose que vous ne pensez pas vraiment ce que vous dites ;-). Ce n'est pas une bonne forme (ni lisible, ni efficace) d'utiliser directement des méthodes spéciales - elles sont plutôt destinées à être utilisées à travers les opérateurs et les commandes intégrées qui leur sont déléguées.
in Chaînes et listes PythonVoici quelques exemples utiles qui parlent d'eux-mêmes concernant la inméthode:
"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]
Caveat. Les listes sont des itérables, et la inméthode agit sur les itérables, pas seulement sur les chaînes.
["bar", "foo", "foobar"] in "foof":?
Si vous êtes satisfait "blah" in somestringmais souhaitez que ce soit un appel de fonction / méthode, vous pouvez probablement le faire
import operator
if not operator.contains(somestring, "blah"):
continue
Tous les opérateurs en Python peuvent être plus ou moins trouvés dans le module opérateur, y compris in.
Donc, apparemment, il n'y a rien de similaire pour la comparaison vectorielle. Une façon évidente de le faire en Python serait:
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
inNe vaut rien qui ne devrait pas être utilisé avec des listes car il effectue un balayage linéaire des éléments et est lent à comparer. Utilisez un ensemble à la place, surtout si les tests d'appartenance doivent être effectués à plusieurs reprises.
Vous pouvez utiliser y.count().
Il renverra la valeur entière du nombre de fois qu'une sous-chaîne apparaît dans une chaîne.
Par exemple:
string.count("bah") >> 0
string.count("Hello") >> 1
Voici votre réponse:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Pour vérifier si elle est fausse:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
OU:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item),__iter__(self)et__getitem__(self, key)dans cet ordre pour déterminer si un élément se trouve dans un contenu donné. Implémentez au moins une de ces méthodes pour rendreindisponible votre type personnalisé.