Проверьте, содержит ли элемент списка Python строку внутри другой строки


588

У меня есть список:

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

и хотите искать элементы, которые содержат строку 'abc'. Как я могу это сделать?

if 'abc' in my_list:

проверит, 'abc'существует ли в списке, но он является частью 'abc-123'и 'abc-456', 'abc'не существует сам по себе. Так как я могу получить все предметы, которые содержат 'abc'?


19
Чтобы проверить обратное (если одна строка содержит одну из нескольких строк): stackoverflow.com/a/6531704/2436175
— Антонио

Если левые части записей уникальны, рассмотрите возможность создания дикта из списка: найдите запись в списке на основе частичной строки
— Георгий

Ответы:


931

Если вы хотите проверить наличие abcкакой-либо строки в списке, попробуйте

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

Если вы действительно хотите получить все элементы, содержащие abc, используйте

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

Я должен проверить, есть ли один элемент в массиве из 6 элементов. Это быстрее сделать 6 "если" или это то же самое?
— Оливье Понс

42
@OlivierPons, просто сделайif myitem in myarray:
— alldayremix

8
Другой способ получить все строки, содержащие подстроку 'abc':filter(lambda element: 'abc' in element, some_list)
— driftcatcher

2
@ p014k: используйте index()метод:try: return mylist.index(myitem); except ValueError: pass
— Свен Марнах

1
@midkin: Я не понимаю, что именно ты пытался сделать, и как все пошло не так. Вероятно, вам повезет больше, если вы зададите новый вопрос (с помощью кнопки «Задать вопрос»), скопируете свой точный код, то, что вы ожидали от кода, и что он на самом деле сделал. «Не работает» совершенно бессмысленно, если только вы не определите, что означает «работает» в этом контексте, но даже тогда лучше объяснить, что на самом деле произошло, чем сказать, что не сработало.
— Свен Марнач

104

Просто добавьте это: если вам нужно сопоставить более чем одну строку, например, abcи def, вы можете объединить два понимания следующим образом:

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

Вывод:

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

4
Это было именно то, что я гуглил .. Спасибо!
— N8TRO

2
Вы также можете использовать {s for s in my_list for xs in matchers if xs in s}(обратите внимание на фигурные скобки, чтобы создать уникальный набор). Может быть легче читать, но может быть медленнее, если большинство sзначений будет соответствовать, так как вы anyэффективно остановитесь на первом совпадении.
— Матиас Фрипп

82

Используйте, filterчтобы добраться до элементов, которые имеют abc.

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

Вы также можете использовать понимание списка.

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

Кстати, не используйте слово listв качестве имени переменной, так как оно уже используется для listтипа.


50

Если вам просто нужно знать, есть ли abc в одном из пунктов, это самый короткий путь:

if 'abc' in str(my_list):

1
Это не получится, если у вас будет список ["abc1", "1abc2"], поскольку он найдет совпадение, потому что строка 'abc' будет во вновь созданной строке
— cgseller

2
Да, это предполагаемое поведение ... верно, если какой-либо из элементов содержит 'abc'
— RogerS

7
Я не знаю, почему все эти другие люди решают делать эти запутанные лямбда-решения, когда им это не нужно! Отличная работа @RogerS
— ntk4

1
На самом деле тот же вопрос почти отвечает сам на себя ... Я только добавил 3 буквы к нему.
— RogerS

1
Это хорошее решение, но если вы хотите найти элементы, содержащие данную строку, у вас ничего не получится. Здесь вы узнаете, содержит ли какой-либо из элементов строку.
— cslotty

18

Это довольно старый вопрос, но я предлагаю этот ответ, потому что предыдущие ответы не справляются с элементами в списке, которые не являются строками (или неким итеративным объектом). Такие элементы могут привести к сбою в понимании всего списка за исключением.

Чтобы изящно обрабатывать такие элементы в списке, пропуская не повторяемые элементы, используйте следующее:

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

тогда с таким списком:

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

вы все равно получите соответствующие предметы ( ['abc-123', 'abc-456'])

Тест на повторяемость может быть не лучшим. Получил это отсюда: в Python, как мне определить, является ли объект итеративным?


Не будет [el for el in lst if el and (st in el)]больше смысла в данном примере?
— Гордо

@tinix Я не думаю, что изящно будет обрабатывать не повторяемые объекты, не так ли?
— Роберт Мюил

«данный пример» my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] не нужно слишком усложнять.
— Гордо

1
Да, безусловно - принятый ответ идеально подходит, а мое предложение более сложное, поэтому не стесняйтесь его игнорировать - я просто предложил на случай, если у кого-то возникла та же проблема, что и у меня: не повторяющиеся элементы в таких списках - это реальная возможность несмотря на отсутствие в данном примере.
— Роберт Мюил,


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

3
Если вы собираетесь использовать этот подход, я думаю, что это более идиоматично, чем if 'abc' in itemиспользовать item.find('abc') == -1.
— Уайетт Болдуин



3

Я новичок в Python. Я получил приведенный ниже код и сделал его легким для понимания:

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)

В Python3.6 это дает ошибку: TypeError: ожидаемая строка или
— байтовоподобный

1
@AimForClarity Да. re.findall в python3.6 ожидает строку. Альтернативой может быть преобразование списка в строку 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
Извините за плохое форматирование. По какой-то причине не может сделать правильные разрывы строк.
— arun_munagala

0

Я сделал поиск, который требует от вас ввести определенное значение, затем он будет искать значение из списка, который содержит ваш ввод:

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)

Попробуйте найти «abc».



0

Мне нужны были индексы списка, которые соответствуют совпадению следующим образом:

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

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

вывод

[0, 3]

-1

Вопрос: Дайте информацию 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

Насколько мне известно, утверждение «за» всегда будет занимать время.

Когда длина списка увеличивается, время выполнения также увеличивается.

Я думаю, что поиск подстроки в строке с помощью оператора is немного быстрее.

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

Но я согласен, что это anyутверждение более читабельно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.