Verifique se um item da lista Python contém uma string dentro de outra string

588

Eu tenho uma lista:

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

e deseja procurar itens que contenham a sequência 'abc'. Como eu posso fazer isso?

if 'abc' in my_list:

verificaria se 'abc'existe na lista, mas faz parte de 'abc-123'e 'abc-456', 'abc'não existe por si só. Então, como posso obter todos os itens que contêm 'abc'?

SandyBr
fonte
19
Para verificar o oposto (se uma string contiver uma entre várias strings): stackoverflow.com/a/6531704/2436175
Antonio
Se as partes esquerda de entradas são únicos, considere a construção de um dicionário da lista: Encontrar uma entrada em uma lista com base em uma seqüência parcial
Georgy

Respostas:

931

Se você deseja apenas verificar a presença de abcqualquer string na lista, tente

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

Se você realmente deseja obter todos os itens que contêm abc, use

matching = [s for s in some_list if "abc" in s]
Sven Marnach
fonte
Eu tenho que verificar se um item está em uma matriz de 6 elementos. É mais rápido fazer 6 "se" ou é o mesmo?
Olivier Pons
42
@OlivierPons, just doif myitem in myarray:
alldayremix 21/03
8
Outra maneira de obter todas as cadeias que contêm substring 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher
2
@ p014k: use o index()método:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach
1
@ midkin: Eu não entendo exatamente o que você estava tentando fazer, nem como deu errado. Você provavelmente terá mais sorte fazendo uma nova pergunta (com o botão "Fazer pergunta"), copiando seu código exato, o que você esperaria que o código fizesse e o que realmente fez. "Não funcionou" é completamente sem sentido, a menos que você defina o que "funciona" significa nesse contexto, mas mesmo assim é melhor explicar o que realmente aconteceu em vez de dizer o que não funcionou.
Sven Marnach
104

Apenas divulgando isso: se você precisar corresponder a mais de uma string, por exemplo , abce defpoderá combinar duas compreensões da seguinte maneira:

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

Resultado:

['abc-123', 'def-456', 'abc-456']
fantabolous
fonte
4
Era exatamente para isso que eu estava pesquisando .. Obrigado!
N8TRO 6/07
2
Você também pode usar {s for s in my_list for xs in matchers if xs in s}(observe os colchetes para criar um conjunto exclusivo). Pode ser mais fácil de ler, mas pode ser mais lento se a maioria dos svalores tiver uma correspondência, pois sua anyparada será eficiente na primeira correspondência.
Matthias Fripp
82

Use filterpara obter os elementos que possuem abc.

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

Você também pode usar uma compreensão de lista.

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

A propósito, não use a palavra listcomo um nome de variável, pois ela já é usada para o listtipo.

MAK
fonte
50

Se você só precisa saber se 'abc' está em um dos itens, esta é a maneira mais curta:

if 'abc' in str(my_list):
RogerS
fonte
1
Isso falharia se você tivesse uma lista de ["abc1", "1abc2"], pois encontraria uma correspondência porque a string 'abc' estaria na string recém-criada
cgseller
2
Sim, este é o comportamento desejado ... verdadeiro se qualquer um dos itens contêm 'abc'
Rogers
7
Não sei por que todas essas outras pessoas decidem fazer essas soluções lambda complicadas quando não precisam! Bom trabalho @RogerS
ntk4
1
Na verdade, a mesma pergunta quase responde a si mesma ... Acabei de adicionar 3 letras a ela.
Rogers
1
É uma boa solução, mas se você deseja encontrar os itens que contêm a sequência especificada, não terá êxito. Aqui você descobre se algum dos itens contém a sequência.
Cslotty 9/05/19
18

Essa é uma pergunta bastante antiga, mas ofereço esta resposta porque as respostas anteriores não lidam com itens da lista que não são cadeias de caracteres (ou algum tipo de objeto iterável). Esses itens causariam uma falha na compreensão da lista inteira, com uma exceção.

Para lidar com esses itens normalmente na lista, ignorando os itens não iteráveis, use o seguinte:

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

então, com essa lista:

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

você ainda receberá os itens correspondentes ( ['abc-123', 'abc-456'])

O teste para iterável pode não ser o melhor. Entendi a partir daqui: No Python, como determino se um objeto é iterável?

Robert Muil
fonte
Não [el for el in lst if el and (st in el)]faria mais sentido no exemplo dado?
Gordo #
@tinix Eu não que lida com objetos não iteráveis ​​normalmente, não é?
Robert Muil
"exemplo dado" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] não há necessidade de complicar demais.
Gordo #
1
Sim, absolutamente - a resposta aceita é perfeitamente adequada e minha sugestão é mais complicada, portanto, fique à vontade para ignorá-la - acabei de oferecer caso alguém tivesse o mesmo problema que eu: itens não iteráveis ​​nessas listas são uma possibilidade do mundo real apesar de não existir no exemplo dado.
Robert Muil
13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]
Mariy
fonte
10
for item in my_list:
    if item.find("abc") != -1:
        print item
Rubycon
fonte
3
Se você seguir essa abordagem, acho mais idiomático if 'abc' in itemusar um pouco item.find('abc') == -1.
Wyatt Baldwin
6
any('abc' in item for item in mylist)
Imran
fonte
4

Use o __contains__()método da classe de string Pythons .:

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

Eu sou novo no Python. Coloquei o código abaixo funcionando e facilitei a compreensão:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for str in my_list:
    if 'abc' in str:
       print(str)
Amol Manthalkar
fonte
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)
Chandra
fonte
0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)
arun_munagala
fonte
Em Python3.6 isso dá um erro: TypeError: string esperado ou bytes-como objeto
AimForClarity
1
@AimForClarity Sim. re.findall em python3.6 espera uma string. Uma alternativa seria através da conversão de uma lista em uma string 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
Desculpe pela má formatação. Não foi possível fazer quebras de linha adequadas por algum motivo.
Arun_munagala
0

Eu fiz uma pesquisa, que exige que você insira um determinado valor, e ele procurará um valor da lista que contém sua entrada:

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)

Tente pesquisar por 'abc'.

Jayson Ogso
fonte
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?")
Raja Ahsan Zeb
fonte
0

Eu precisava dos índices da lista que correspondam a uma correspondência da seguinte maneira:

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

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

resultado

[0, 3]
Grant Shannon
fonte
-1

Pergunta: Dê as informações de 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']
Soudipta Dutta
fonte
-2

Pelo que sei, uma declaração 'for' sempre consumirá tempo.

Quando o tamanho da lista cresce, o tempo de execução também aumenta.

Eu acho que, pesquisar uma substring em uma string com a declaração 'is' é um pouco mais rápido.

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

Mas, eu concordo que a anyafirmação é mais legível.

Iulian
fonte