Verifica se un elemento dell'elenco Python contiene una stringa all'interno di un'altra stringa


588

Ho un elenco:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

e vuoi cercare elementi che contengono la stringa 'abc'. Come lo posso fare?

if 'abc' in my_list:

controlla se 'abc'esiste nell'elenco ma fa parte di 'abc-123'e 'abc-456', 'abc'non esiste da solo. Quindi, come posso ottenere tutti gli articoli che contengono 'abc'?


19
Per verificare il contrario (se una stringa ne contiene una tra più stringhe): stackoverflow.com/a/6531704/2436175
Antonio,

Se le parti a sinistra delle voci sono uniche, prendi in considerazione la costruzione di un dict dall'elenco: trova una voce in un elenco in base a una stringa parziale
Georgy,

Risposte:


931

Se vuoi solo verificare la presenza di abcqualsiasi stringa nell'elenco, puoi provare

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

Se vuoi davvero ottenere tutti gli articoli che contengono abc, usa

matching = [s for s in some_list if "abc" in s]

Devo verificare se un elemento si trova in una matrice di 6 elementi. È più veloce fare 6 "if" o è lo stesso?
Olivier Pons

42
@OlivierPons, bastaif myitem in myarray:
alldayremix

8
Un altro modo per ottenere tutte le stringhe contenenti sottostringa 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher

2
@ p014k: utilizzare il index()metodo:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach,

1
@midkin: non capisco esattamente cosa stavi cercando di fare, né come sia andato storto. Probabilmente avrai più fortuna ponendo una nuova domanda (con il pulsante "Poni domanda"), copiando il tuo codice esatto, cosa ti aspetteresti che faccia il codice e cosa ha effettivamente fatto. "Non ha funzionato" è completamente insignificante se non si definisce cosa significa "funziona" in questo contesto, ma anche in questo caso è meglio spiegare cosa è realmente accaduto invece di dire cosa non ha funzionato.
Sven Marnach,

104

Basta buttare questo là fuori: se vi capita di necessità di adeguare contro più di una stringa, per esempio abce def, è possibile combinare due comprensioni come segue:

matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

Produzione:

['abc-123', 'def-456', 'abc-456']

4
Era esattamente quello per cui stavo cercando su Google .. Grazie!
N8TRO,

2
Puoi anche usare {s for s in my_list for xs in matchers if xs in s}(nota le parentesi graffe per creare un set unico). Potrebbe essere più facile da leggere, ma potrebbe essere più lento se la maggior parte dei svalori avrà una corrispondenza, poiché anyalla prima partita ti fermerai in modo efficiente.
Matthias Fripp,

82

Utilizzare filterper ottenere gli elementi che hanno abc.

>>> lst = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> print filter(lambda x: 'abc' in x, lst)
['abc-123', 'abc-456']

Puoi anche usare una comprensione dell'elenco.

>>> [x for x in lst if 'abc' in x]

A proposito, non usare la parola listcome nome di una variabile poiché è già utilizzata per il listtipo.


50

Se hai solo bisogno di sapere se 'abc' si trova in uno degli elementi, questo è il modo più breve:

if 'abc' in str(my_list):

1
Ciò fallirebbe se avessi un elenco di ["abc1", "1abc2"] in quanto troverebbe una corrispondenza perché la stringa 'abc' sarebbe nella stringa appena creata
cgseller,

2
Sì, questo è il comportamento previsto ... vero se qualcuno degli elementi contiene "abc"
RogerS

7
Non so perché tutte queste altre persone decidano di fare quelle soluzioni lambda contorte quando non ne hanno bisogno! Bel lavoro @RogerS
ntk4

1
In realtà la stessa domanda quasi risponde a se stessa ... Ho appena aggiunto 3 lettere ad esso.
RogerS,

1
È una buona soluzione, ma se vuoi trovare gli elementi che contengono la stringa data, non ci riuscirai. Qui scopri se uno degli elementi contiene la stringa.
cslotty

18

Questa è una domanda piuttosto vecchia, ma offro questa risposta perché le risposte precedenti non affrontano elementi nell'elenco che non sono stringhe (o qualche tipo di oggetto iterabile). Tali elementi farebbero fallire la comprensione dell'intera lista con un'eccezione.

Per gestire con grazia tali elementi nell'elenco saltando gli elementi non iterabili, utilizzare quanto segue:

[el for el in lst if isinstance(el, collections.Iterable) and (st in el)]

quindi, con un tale elenco:

lst = [None, 'abc-123', 'def-456', 'ghi-789', 'abc-456', 123]
st = 'abc'

otterrai comunque gli articoli corrispondenti ( ['abc-123', 'abc-456'])

Il test per iterable potrebbe non essere il migliore. Capito da qui: in Python, come posso determinare se un oggetto è iterabile?


Non avrebbe [el for el in lst if el and (st in el)]più senso nell'esempio dato?
Gordo,

@tinix Non gestirò con grazia oggetti non iterabili, vero?
Robert Muil,

"esempio dato" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] non è necessario complicarlo eccessivamente.
Gordo,

1
Sì assolutamente - la risposta accettata è perfettamente adatta e il mio suggerimento è più complicato, quindi sentiti libero di ignorarlo - Ho appena offerto nel caso in cui qualcuno avesse lo stesso problema che avevo: gli elementi non ripetibili in tali elenchi sono una possibilità reale nonostante non esista nell'esempio dato.
Robert Muil,

13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

10
for item in my_list:
    if item.find("abc") != -1:
        print item

3
Se hai intenzione di adottare questo approccio, penso che sia più idiomatico fare if 'abc' in itempiuttosto che usare item.find('abc') == -1.
Wyatt Baldwin,


4

Usa il __contains__()metodo della classe di stringhe Pythons .:

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")

3

Sono nuovo di Python. Ho ottenuto il codice qui sotto funzionante e reso facile da capire:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for str in my_list:
    if 'abc' in str:
       print(str)

0
my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

for item in my_list:
    if (item.find('abc')) != -1:
        print ('Found at ', item)

0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)

In Python3.6 viene visualizzato un errore: TypeError: stringa attesa o oggetto simile a byte
AimForClarity

1
@AimForClarity Sì. re.findall in python3.6 prevede una stringa. Un'alternativa sarebbe quella di convertire l'elenco in una stringa import re mylist=['abc','def','ghi','abcff'] my_list_string=''.join(mylist) string_to_find="abc" res=re.findall(string_to_find,my_list_string) print(res)
arun_munagala

1
Ci scusiamo per la scarsa formattazione. Non è possibile eseguire le interruzioni di riga appropriate per qualche motivo.
arun_munagala,

0

Ho fatto una ricerca, che richiede di inserire un certo valore, quindi cercherà un valore dall'elenco che contiene il tuo input:

my_list = ['abc-123',
        'def-456',
        'ghi-789',
        'abc-456'
        ]

imp = raw_input('Search item: ')

for items in my_list:
    val = items
    if any(imp in val for items in my_list):
        print(items)

Prova a cercare "abc".


0
def find_dog(new_ls):
    splt = new_ls.split()
    if 'dog' in splt:
        print("True")
    else:
        print('False')


find_dog("Is there a dog here?")

0

Avevo bisogno degli indici dell'elenco che corrispondono a una corrispondenza come segue:

lst=['abc-123', 'def-456', 'ghi-789', 'abc-456']

[n for n, x in enumerate(lst) if 'abc' in x]

produzione

[0, 3]

-1

Domanda: fornire le informazioni di abc

    a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']


    aa = [ string for string in a if  "abc" in string]
    print(aa)

Output =>  ['abc-123', 'abc-456']

-2

Per quanto ne so, un'affermazione "for" richiederà sempre tempo.

Quando la lunghezza dell'elenco aumenta, aumenta anche il tempo di esecuzione.

Penso che cercare una sottostringa in una stringa con l'istruzione "is" sia un po 'più veloce.

In [1]: t = ["abc_%s" % number for number in range(10000)]

In [2]: %timeit any("9999" in string for string in t)
1000 loops, best of 3: 420 µs per loop

In [3]: %timeit "9999" in ",".join(t)
10000 loops, best of 3: 103 µs per loop

Ma, sono d'accordo che l' anyaffermazione è più leggibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.