Проверьте, содержит ли элемент списка 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.