Vérifiez si un élément de liste Python contient une chaîne à l'intérieur d'une autre chaîne

588

J'ai une liste:

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

et souhaitez rechercher des éléments contenant la chaîne 'abc'. Comment puis je faire ça?

if 'abc' in my_list:

vérifierait si 'abc'existe dans la liste , mais il est une partie 'abc-123'et 'abc-456', 'abc'n'existe pas sur lui - même. Alors, comment puis-je obtenir tous les articles qui contiennent 'abc'?

SandyBr
la source
19
Pour vérifier le contraire (si une chaîne en contient une parmi plusieurs chaînes): stackoverflow.com/a/6531704/2436175
Antonio
Si les parties gauches des entrées sont uniques, envisagez de construire un dict à partir de la liste: Recherchez une entrée dans une liste basée sur une chaîne partielle
Georgy

Réponses:

931

Si vous souhaitez uniquement vérifier la présence de abcdans n'importe quelle chaîne de la liste, vous pouvez essayer

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

Si vous voulez vraiment obtenir tous les éléments contenant abc, utilisez

matching = [s for s in some_list if "abc" in s]
Sven Marnach
la source
Je dois vérifier si un élément est dans un tableau de 6 éléments. Est-il plus rapide de faire 6 "si" ou est-ce la même chose?
Olivier Pons
42
@OlivierPons, faites-leif myitem in myarray:
alldayremix
8
Une autre façon d'obtenir toutes les chaînes contenant la sous-chaîne 'abc':filter(lambda element: 'abc' in element, some_list)
driftcatcher
2
@ p014k: utilisez la index()méthode:try: return mylist.index(myitem); except ValueError: pass
Sven Marnach
1
@midkin: Je ne comprends pas exactement ce que vous essayez de faire, ni comment cela s'est mal passé. Vous aurez probablement plus de chance en posant une nouvelle question (avec le bouton "Poser une question"), en copiant votre code exact, ce que vous vous attendiez à ce que le code fasse et ce qu'il a réellement fait. "N'a pas fonctionné" n'a aucun sens sauf si vous définissez ce que "fonctionne" signifie dans ce contexte, mais même dans ce cas, il vaut mieux expliquer ce qui s'est réellement passé au lieu de dire ce qui n'a pas fonctionné.
Sven Marnach
104

Il suffit de lancer ceci: si vous devez correspondre à plusieurs chaînes, par exemple abcet def, vous pouvez combiner deux compréhensions comme suit:

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

Production:

['abc-123', 'def-456', 'abc-456']
fantabolique
la source
4
C'est exactement pour cela que je cherchais sur Google. Merci!
N8TRO
2
Vous pouvez également utiliser {s for s in my_list for xs in matchers if xs in s}(notez les accolades pour créer un ensemble unique). Peut être plus facile à lire, mais peut être plus lent si la plupart des svaleurs ont une correspondance, car vous vous anyarrêterez efficacement lors de la première correspondance.
Matthias Fripp
82

Utilisez filterpour accéder aux éléments qui ont abc.

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

Vous pouvez également utiliser une liste de compréhension.

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

Soit dit en passant, n'utilisez pas le mot listcomme nom de variable car il est déjà utilisé pour le listtype.

MAK
la source
50

Si vous avez juste besoin de savoir si 'abc' est dans l'un des éléments, c'est le moyen le plus court:

if 'abc' in str(my_list):
RogerS
la source
1
Cela échouerait si vous aviez une liste de ["abc1", "1abc2"] car il trouverait une correspondance car la chaîne 'abc' serait dans la chaîne nouvellement créée
cgseller
2
Oui, c'est le comportement prévu ... vrai si l'un des éléments contient 'abc'
RogerS
7
Je ne sais pas pourquoi toutes ces autres personnes décident de faire ces solutions lambda alambiquées alors qu'elles n'en ont pas besoin! Beau travail @RogerS
ntk4
1
En fait, la même question se répond presque d'elle-même ... Je viens d'y ajouter 3 lettres.
RogerS
1
C'est une bonne solution, mais si vous voulez trouver les éléments qui contiennent la chaîne donnée, vous ne réussirez pas. Ici, vous découvrez si l' un des éléments contient la chaîne.
cslotty
18

C'est une question assez ancienne, mais je propose cette réponse car les réponses précédentes ne traitent pas des éléments de la liste qui ne sont pas des chaînes (ou une sorte d'objet itérable). De tels éléments entraîneraient l'échec de la compréhension de la liste entière avec une exception.

Pour traiter gracieusement ces éléments de la liste en ignorant les éléments non itérables, utilisez ce qui suit:

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

puis, avec une telle liste:

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

vous obtiendrez toujours les articles correspondants ( ['abc-123', 'abc-456'])

Le test d'itérable n'est peut-être pas le meilleur. Je l'ai ici: en Python, comment puis-je déterminer si un objet est itérable?

Robert Muil
la source
Cela n'aurait pas [el for el in lst if el and (st in el)]plus de sens dans l'exemple donné?
Gordo
@tinix Je ne gère pas les objets non itérables avec élégance, n'est-ce pas?
Robert Muil
"exemple donné" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] pas besoin de trop le compliquer.
Gordo
1
Oui absolument - la réponse acceptée convient parfaitement et ma suggestion est plus compliquée, alors n'hésitez pas à l'ignorer - je viens de proposer au cas où quelqu'un aurait le même problème que moi: les éléments non itérables de ces listes sont une possibilité réelle bien qu'il n'existe pas dans l'exemple donné.
Robert Muil
13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]
Mariy
la source
10
for item in my_list:
    if item.find("abc") != -1:
        print item
Rubycon
la source
3
Si vous allez adopter cette approche, je pense qu'il est plus idiomatique de faire if 'abc' in itemplutôt usage item.find('abc') == -1.
Wyatt Baldwin
6
any('abc' in item for item in mylist)
Imran
la source
4

Utilisez la __contains__()méthode de la classe de chaîne Pythons:

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

Je suis nouveau sur Python. J'ai fait fonctionner le code ci-dessous et je l'ai rendu facile à comprendre:

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

pattern=re.compile(r'abc') 

pattern.findall(mylist)
arun_munagala
la source
En Python3.6, cela donne une erreur: TypeError: chaîne attendue ou objet semblable à des octets
AimForClarity
1
@AimForClarity Oui. re.findall en python3.6 attend une chaîne. Une alternative serait de convertir la liste en une chaîne 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
Désolé pour le mauvais formatage. Impossible de faire des sauts de ligne appropriés pour une raison quelconque.
arun_munagala
0

J'ai fait une recherche, qui vous oblige à entrer une certaine valeur, puis il recherchera une valeur dans la liste qui contient votre entrée:

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)

Essayez de rechercher 'abc'.

Jayson Ogso
la source
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
la source
0

J'avais besoin des indices de liste qui correspondent à une correspondance comme suit:

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

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

production

[0, 3]
Grant Shannon
la source
-1

Question: Donnez les informations 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
la source
-2

D'après mes connaissances, une déclaration «pour» prendra toujours du temps.

Lorsque la longueur de la liste augmente, le temps d'exécution augmente également.

Je pense que, la recherche d'une sous-chaîne dans une chaîne avec la déclaration «is» est un peu plus rapide.

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

Mais, je suis d'accord que la anydéclaration est plus lisible.

Iulian
la source