Respuestas:
Puedes usar el in
operador :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
utiliza el operador Python el algoritmo Rabin-Carp?
Si es solo una búsqueda de subcadenas, puede usarla string.find("substring")
.
Usted tiene que ser un poco cuidadoso con find
, index
y in
sin embargo, a medida que se subcadena búsquedas. En otras palabras, esto:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Se imprimiría de Found 'is' in the string.
manera similar, if "is" in s:
se evaluaría a True
. Esto puede o no ser lo que quieres.
if ' is ' in s:
cuál regresará False
como se espera (probablemente).
\bis\b
(límites de palabras).
' is '
, en particular, no atrapará This is, a comma'
o no 'It is.'
.
s.split(string.punctuation + string.whitespace)
se dividiría incluso una vez; split
no es como la familia de funciones strip
/ rstrip
/ lstrip
, solo se divide cuando ve todos los caracteres delimitadores, contiguamente, en ese orden exacto. Si desea dividir en clases de caracteres, vuelve a las expresiones regulares (en ese momento, buscar r'\bis\b'
sin dividir es la forma más sencilla y rápida de hacerlo).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()
- Ok, punto tomado. Esto ahora es ridículo ...
¿Python tiene una cadena que contiene el método de subcadena?
Sí, pero Python tiene un operador de comparación que debería usar en su lugar, porque el lenguaje pretende su uso, y otros programadores esperarán que lo use. Esa palabra clave es in
, que se utiliza como operador de comparación:
>>> 'foo' in '**foo**'
True
El opuesto (complemento), que pide la pregunta original, es not in
:
>>> 'foo' not in '**foo**' # returns False
False
Esto es semánticamente igual, not 'foo' in '**foo**'
pero es mucho más legible y se proporciona explícitamente en el lenguaje como una mejora de legibilidad.
__contains__
, find
yindex
Según lo prometido, este es el contains
método:
str.__contains__('**foo**', 'foo')
vuelve True
. También podría llamar a esta función desde la instancia de la supercadena:
'**foo**'.__contains__('foo')
Pero no lo hagas. Los métodos que comienzan con guiones bajos se consideran semánticamente privados. La única razón para usar esto es cuando se extiende la funcionalidad in
y not in
(por ejemplo, si se subclasifica 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')
y ahora:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Además, evite los siguientes métodos de cadena:
>>> '**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
Otros lenguajes pueden no tener métodos para probar directamente las subcadenas, por lo que tendría que usar este tipo de métodos, pero con Python, es mucho más eficiente usar el in
operador de comparación.
Podemos comparar varias formas de lograr el mismo objetivo.
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'))),
}
Y ahora vemos que usar in
es mucho más rápido que los demás. Menos tiempo para hacer una operación equivalente es mejor:
>>> 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
y str.find
? ¿De qué otra forma sugeriría que alguien encuentre el índice de una subcadena en lugar de solo si existe o no? (¿o quiso decir evitar usarlos en lugar de s.find(ss) != -1
ss in s
re
módulo. Todavía no he encontrado un uso para str.index o str.find en cualquier código que haya escrito todavía.
str.count
también ( string.count(something) != 0
). estremecimiento
operator
versión del módulo ?
in_
anterior, pero con un marco de pila alrededor, por lo que es más lento que eso: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:
es el uso normal, como dice @Michael: se basa en el in
operador, más legible y más rápido que una llamada a método.
Si realmente necesita un método en lugar de un operador (por ejemplo, hacer algo extraño key=
para un tipo muy peculiar ...?), Sería 'haystack'.__contains__
. Pero dado que su ejemplo es para usar en un if
, supongo que realmente no quiere decir lo que dice ;-). No es una buena forma (ni legible, ni eficiente) usar métodos especiales directamente; están destinados a ser utilizados, en cambio, a través de los operadores y las incorporaciones que les delegan.
in
Python cadenas y listasAquí hay algunos ejemplos útiles que hablan por sí mismos sobre el in
método:
"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]
Consideración. Las listas son iterables, y el in
método actúa en iterables, no solo en cadenas.
["bar", "foo", "foobar"] in "foof"
:?
Entonces, aparentemente no hay nada similar para la comparación vectorial. Una forma obvia de hacerlo en Python sería:
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
no deba usarse con listas porque hace un escaneo lineal de los elementos y es lento en comparación. Utilice un conjunto en su lugar, especialmente si las pruebas de membresía se deben realizar repetidamente.
Puedes usar y.count()
.
Devolverá el valor entero de la cantidad de veces que aparece una subcadena en una cadena.
Por ejemplo:
string.count("bah") >> 0
string.count("Hello") >> 1
Aquí está tu respuesta:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Para verificar si es falso:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
O:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item)
,__iter__(self)
y__getitem__(self, key)
en ese orden a determinar si un elemento se encuentra en un determinado contiene. Implemente al menos uno de esos métodos para que estéin
disponible para su tipo personalizado.