Respostas:
Você pode usar o in
operador :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
operador Python usa o algoritmo Rabin-Carp?
Se for apenas uma pesquisa de substring, você pode usar string.find("substring")
.
Você tem que ser um pouco cuidadoso com find
, index
e, in
no entanto, como eles são substring pesquisas. Em outras palavras, isso:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Seria imprimir Found 'is' in the string.
Da mesma forma, if "is" in s:
avaliaria para True
. Isso pode ou não ser o que você deseja.
if ' is ' in s:
que retornará False
como é (provavelmente) esperado.
\bis\b
(limites de palavras).
' is '
, notavelmente, ela não pegará This is, a comma'
ou 'It is.'
.
s.split(string.punctuation + string.whitespace)
seja dividida uma vez; split
não é como a família strip
/ rstrip
/ lstrip
de funções, apenas se divide quando vê todos os caracteres delimitadores, contiguamente, nessa ordem exata. Se você deseja dividir as classes de caracteres, volta às expressões regulares (nesse ponto, procurar r'\bis\b'
sem dividir é o caminho mais simples e rápido).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()
- ok, ponto de vista. Isto agora é ridículo ...
O Python possui uma string que contém o método de substring?
Sim, mas o Python possui um operador de comparação que você deve usar, porque a linguagem pretende seu uso, e outros programadores esperam que você o use. Essa palavra-chave é in
usada como um operador de comparação:
>>> 'foo' in '**foo**'
True
O oposto (complemento), que a pergunta original pede, é not in
:
>>> 'foo' not in '**foo**' # returns False
False
É semanticamente o mesmo, not 'foo' in '**foo**'
mas é muito mais legível e explicitamente previsto no idioma como uma melhoria de legibilidade.
__contains__
, find
eindex
Como prometido, aqui está o contains
método:
str.__contains__('**foo**', 'foo')
retorna True
. Você também pode chamar esta função a partir da instância da supercorda:
'**foo**'.__contains__('foo')
Mas não. Os métodos que começam com sublinhados são considerados semanticamente privados. A única razão para usar isso é ao estender a funcionalidade in
e not in
(por exemplo, se estiver subclassificando 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')
e agora:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Além disso, evite os seguintes métodos de string:
>>> '**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
Outras linguagens podem não ter métodos para testar diretamente substrings e, portanto, você teria que usar esses tipos de métodos, mas com o Python, é muito mais eficiente usar o in
operador de comparação.
Podemos comparar várias maneiras de alcançar o mesmo 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'))),
}
E agora vemos que o uso in
é muito mais rápido que os outros. Menos tempo para realizar uma operação equivalente é melhor:
>>> 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
e str.find
? De que outra forma você sugeriria que alguém encontrasse o índice de uma substring em vez de apenas existir ou não? (ou você evitar média de usá-los no lugar de contém - portanto, não use s.find(ss) != -1
em vez de ss in s
?)
re
módulo. Ainda não encontrei um uso para str.index ou str.find em qualquer código que eu escrevi ainda.
str.count
também ( string.count(something) != 0
). shudder
operator
versão do módulo ?
in_
acima - mas com um StackFrame em torno dele, por isso é mais lento do que isso: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:
é o uso normal, como o @Michael diz - depende do in
operador, mais legível e mais rápido que uma chamada de método.
Se você realmente precisa de um método em vez de um operador (por exemplo, fazer algo estranho key=
para um tipo muito peculiar ...?), Isso seria 'haystack'.__contains__
. Mas como seu exemplo é para uso em um if
, acho que você não está realmente falando sério ;-). Não é uma boa forma (nem legível, nem eficiente) usar métodos especiais diretamente - eles devem ser usados, em vez disso, através dos operadores e componentes internos que os delegam.
in
Strings e listas PythonAqui estão alguns exemplos úteis que falam por si sobre o 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]
Embargo. Listas são iteráveis, e o in
método atua em iterables, não apenas em strings.
["bar", "foo", "foobar"] in "foof"
:?
Se você está satisfeito, "blah" in somestring
mas deseja que seja uma chamada de função / método, provavelmente poderá fazer isso
import operator
if not operator.contains(somestring, "blah"):
continue
Todos os operadores no Python podem ser mais ou menos encontrados no módulo do operador inclusive in
.
Então, aparentemente, não há nada semelhante para a comparação vetorial. Uma maneira óbvia de Python para fazer isso seria:
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
não deva ser usado com listas porque faz uma varredura linear dos elementos e é lento em comparação. Use um conjunto, especialmente se os testes de associação forem feitos repetidamente.
Você pode usar y.count()
.
Ele retornará o valor inteiro do número de vezes que uma sub string aparecerá em uma string.
Por exemplo:
string.count("bah") >> 0
string.count("Hello") >> 1
Aqui está a sua resposta:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Para verificar se é falso:
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)
e__getitem__(self, key)
nessa ordem para determinar se um item está em um determinado conteúdo. Implemente pelo menos um desses métodos parain
disponibilizar seu tipo personalizado.