substring stringhe - Python ha una stringa "contiene" metodo di sottostringa?




metodi eliminare (13)

Puoi usare l' operatore in :

if "blah" not in somestring: 
    continue

Sto cercando un metodo string.contains o string.indexof in Python.

Voglio fare:

if not somestring.contains("blah"):
   continue

No, non c'è alcun string.contains(str) , ma c'è l'operatore in:

if substring in someString:
    print "It's there!!!"

Ecco un esempio di lavoro più complesso:

# Print all files with dot in home directory
import commands
(st, output) = commands.getstatusoutput('ls -a ~')
print [f for f in output.split('\n') if '.' in f ]

In Python ci sono due semplici modi per ottenere questo risultato:

Il modo Pythonic: usare le parole chiave "in" di Python-

in prende due "argomenti", uno a sinistra ( sottostringa ) e uno a destra, e restituisce True se l'argomento di sinistra è contenuto nell'argomento rightide e in caso contrario restituisce False .

example_string = "This is an example string"
substring = "example"
print(substring in example_string)

Produzione:

True

Il modo non-Pythonic: Usare str.find di Python:

Il metodo find restituisce la posizione della stringa all'interno della stringa o -1 se non è stata trovata. Ma controlla semplicemente se la posizione non è -1.

if example_string.find(substring) != -1:
    print('Substring found!')
else:
    print('Substring not found!')

Produzione:

Substring found!

Se stai cercando la ricerca insensibile alle maiuscole per parole intere, piuttosto che una sottostringa contenuta in un'altra parola:

import string

s = 'This is my text example'
if 'is' not in (word.lower() 
    for split_char in string.punctuation + string.whitespace 
    for word in s.split(split_char)):
    # do something

Se sei felice con "blah" in somestring ma vuoi che sia una chiamata di funzione, puoi probabilmente farlo

import operator

if not operator.contains(somestring, "blah"):
    continue

Tutti gli operatori in Python possono essere più o meno trovati nel modulo operatore incluso in .


Python ha una stringa che contiene il metodo della sottostringa?

Sì, ma Python ha un operatore di confronto che dovresti usare, perché la lingua intende utilizzarlo e altri programmatori si aspettano che tu lo usi. Quella parola chiave è in , che viene utilizzata come operatore di confronto:

>>> 'foo' in '**foo**'
True

Il contrario (complemento), che la domanda originale richiede, not in è not in :

>>> 'foo' not in '**foo**' # returns False
False

Questo è semanticamente uguale a not 'foo' in '**foo**' ma è molto più leggibile e esplicitamente previsto nella lingua come miglioramento della leggibilità.

Evita di usare __contains__ , find e index

Come promesso, ecco il metodo contains :

str.__contains__('**foo**', 'foo')

ritorna True . Puoi anche chiamare questa funzione dall'istanza della superstringa:

'**foo**'.__contains__('foo')

Ma non farlo. I metodi che iniziano con underscore sono considerati semanticamente privati. L'unica ragione per usarlo è quando estendi il in e not in funzionalità (es. Se sottoclasse 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 adesso:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

Inoltre, evitare i seguenti metodi di stringa:

>>> '**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

Altre lingue potrebbero non avere metodi per testare direttamente le sottostringhe, e quindi dovresti usare questi tipi di metodi, ma con Python è molto più efficiente usare l'operatore di confronto.

Confronti delle prestazioni

Possiamo confrontare vari modi per raggiungere lo stesso obiettivo.

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 ora vediamo che l'uso in è molto più veloce degli altri. Meno tempo per fare un'operazione equivalente è meglio:

>>> 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}

if needle in haystack: è l'uso normale, come dice @Michael - si basa sull'operatore in , più leggibile e più veloce di una chiamata al metodo.

Se hai veramente bisogno di un metodo invece di un operatore (ad esempio per fare qualche strana key= per un tipo molto particolare ...?), Quello sarebbe 'haystack'.__contains__ . Ma dal momento che il tuo esempio è per l'uso in un if , immagino che non intendi davvero quello che dici ;-). Non è una buona forma (né leggibile, né efficiente) usare direttamente metodi speciali - sono pensati per essere usati, invece, attraverso gli operatori e i builtin che li delegano.


Se si tratta solo di una ricerca di sottostringa, è possibile utilizzare string.find("substring") .

Devi essere un po 'cauto con find , index e in però, dato che sono ricerche di sottostringa. In altre parole, questo:

s = "This be a string"
if s.find("is") == -1:
    print "No 'is' here!"
else:
    print "Found 'is' in the string."

Stamperebbe Found 'is' in the string. Allo stesso modo, if "is" in s: valuterebbe True . Questo può o non può essere quello che vuoi.


Fondamentalmente, vuoi trovare una sottostringa in una stringa in python. Ci sono due modi per cercare una sottostringa in una stringa in Python.

Metodo 1: in operatore

È possibile utilizzare l'operatore in Python per verificare la presenza di una sottostringa. È abbastanza semplice e intuitivo. Restituirà True se la sottostringa è stata trovata nella stringa else False .

>>> "King" in "King's landing"
True

>>> "Jon Snow" in "King's landing"
False

Metodo 2: metodo str.find()

Il secondo metodo consiste nell'utilizzare il metodo str.find() . Qui, chiamiamo il metodo .find() sulla stringa in cui deve essere trovata la sottostringa. Passiamo la sottostringa al metodo find () e controlliamo il suo valore di ritorno. Se il suo valore è diverso da -1, la sottostringa è stata trovata nella stringa, altrimenti no. Il valore restituito è l'indice in cui è stata trovata la sottostringa.

>>> some_string = "valar morghulis"

>>> some_string.find("morghulis")
6

>>> some_string.find("dohaeris")
-1

Ti consiglierei di usare il primo metodo perché è più Pythonic e intuitivo.


Ecco la tua risposta:

if "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

Per verificare se è 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

Vedo che ci sono già risposte, ma voglio aggiungere anche i miei due centesimi.

In Python ci sono funzioni per farlo, ma il metodo più semplice (e per lo più preferito) è usare la parola chiave in :

"test" in "testtext"
True

"abc" in "abcdefg"
True

"abc" in "Abc"
False

"ABC" in "abc"
False

"abc" in "def"
False

"abc" in ["abc", "def", "ghi"]
True

Esistono anche alcuni metodi di stringa:

"xxabcxx".find("abc")
2 #returns the index of the first match

"xxabcxx".find("cde")
-1 #returns -1 if the substring 
#could not be found in the string

# and:

"xxabcxx".index("abc")
2

"xxabcxx".index("cde")
ValueError: substring not found
#raises ValueError...

Informazioni sulle prestazioni:

In generale in è il metodo a digiuno per trovare una sottostringa ...

find è leggermente più veloce index

Spero di poterti aiutare!


in stringhe e liste Python

Ecco alcuni esempi utili che parlano da soli riguardo al metodo in:

"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

Avvertimento. Gli elenchi sono iterabili e il metodo in funziona su iterabili, non solo stringhe.


Collegamento al yield Grokking

Quando vedi una funzione con dichiarazioni di yield , applica questo semplice trucco per capire cosa accadrà:

  1. Inserisci un result = [] riga result = [] all'inizio della funzione.
  2. Sostituisci ogni yield expr con result.append(expr) .
  3. Inserisci un return result riga nella parte inferiore della funzione.
  4. Sì, niente più dichiarazioni di yield ! Leggi e calcola il codice.
  5. Confronta la funzione con la definizione originale.

Questo trucco può darti un'idea della logica alla base della funzione, ma ciò che effettivamente accade con il yield è significativamente diverso da ciò che accade nell'approccio basato sull'elenco. In molti casi, l'approccio di rendimento sarà molto più efficiente in termini di memoria e anche più veloce. In altri casi questo trucco ti farà rimanere bloccato in un ciclo infinito, anche se la funzione originale funziona perfettamente. Continuate a leggere per saperne di più...

Non confondere i tuoi Iterables, Iterators e Generators

Innanzitutto, il protocollo iteratore - quando scrivi

for x in mylist:
    ...loop body...

Python esegue i seguenti due passaggi:

  1. Ottiene un iteratore per mylist :

    Call iter(mylist) -> restituisce un oggetto con un metodo next() (o __next__() in Python 3).

    [Questo è il passo che molte persone dimenticano di dirti]

  2. Utilizza l'iteratore per eseguire il loop degli elementi:

    Continua a chiamare il metodo next() sull'iterator restituito dal passaggio 1. Il valore restituito da next() viene assegnato a x e il corpo del loop viene eseguito. Se viene sollevata un'eccezione StopIteration dall'interno next() , significa che non ci sono più valori nell'iteratore e il ciclo viene chiuso.

La verità è che Python esegue i suddetti due passaggi ogni volta che desidera eseguire il looping dei contenuti di un oggetto, quindi potrebbe essere un ciclo for, ma potrebbe anche essere un codice come otherlist.extend(mylist) (dove otherlist è un elenco Python) .

Qui mylist è iterabile perché implementa il protocollo iteratore. In una classe definita dall'utente, è possibile implementare il __iter__() per rendere iterabili le istanze della classe. Questo metodo dovrebbe restituire un iteratore . Un iteratore è un oggetto con un metodo next() . È possibile implementare sia __iter__() che next() sulla stessa classe e avere __iter__() return self . Ciò funzionerà per casi semplici, ma non quando si desidera che due iteratori eseguano il looping sullo stesso oggetto nello stesso momento.

Quindi questo è il protocollo iteratore, molti oggetti implementano questo protocollo:

  1. Elenchi, dizionari, tuple, insiemi, file incorporati.
  2. Classi definite dall'utente che implementano __iter__() .
  3. Generatori.

Si noti che un ciclo for non conosce il tipo di oggetto con cui si sta occupando - segue solo il protocollo iteratore ed è felice di ottenere item after item come chiama next() . Gli elenchi integrati restituiscono i loro articoli uno per uno, i dizionari restituiscono le chiavi una alla volta, i file restituiscono le righe una per una, ecc. E i generatori restituiscono ... beh, è ​​qui che arriva la yield :

def f123():
    yield 1
    yield 2
    yield 3

for item in f123():
    print item

Invece di dichiarazioni di yield , se avessi tre istruzioni di return in f123() solo il primo verrebbe eseguito e la funzione f123() . Ma f123() non è una funzione ordinaria. Quando viene chiamato f123() , non restituisce alcun valore nelle dichiarazioni di rendimento! Restituisce un oggetto generatore. Inoltre, la funzione non esce realmente - entra in uno stato sospeso. Quando il ciclo for tenta di eseguire il loop sull'oggetto generatore, la funzione riprende dallo stato sospeso alla riga successiva dopo il yield è ritornata in precedenza, esegue la riga successiva del codice, in questo caso un'istruzione yield e la restituisce come il prossimo oggetto. Questo accade fino a quando la funzione non si chiude, a quel punto il generatore solleva StopIteration e il loop termina.

Quindi l'oggetto generatore è un po 'come un adattatore - ad una estremità mostra il protocollo iteratore, esponendo i __iter__() e next() per mantenere felice il ciclo for . All'altro capo, tuttavia, esegue la funzione quel tanto che basta per ricavarne il valore successivo e la rimette in modalità sospesa.

Perché usare i generatori?

Di solito è possibile scrivere codice che non utilizza generatori ma implementa la stessa logica. Un'opzione è usare il "trucco" di elenco temporaneo che ho menzionato prima. Ciò non funzionerà in tutti i casi, ad esempio se si hanno cicli infiniti o se si fa un uso inefficiente della memoria quando si ha una lista molto lunga. L'altro approccio consiste nell'implementare una nuova classe iterabile SomethingIter che mantiene lo stato nei membri di istanza ed esegue il prossimo passo logico nel suo metodo next() (o __next__() in Python 3). A seconda della logica, il codice all'interno del metodo next() può sembrare molto complesso e soggetto a bug. Qui i generatori forniscono una soluzione semplice e pulita.





python string substring contains