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

SandyBr
источник
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']
fantabolous
источник
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типа.

MAK
источник
50

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

if 'abc' in str(my_list):
Rogers
источник
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
Да, безусловно - принятый ответ идеально подходит, а мое предложение более сложное, поэтому не стесняйтесь его игнорировать - я просто предложил на случай, если у кого-то возникла та же проблема, что и у меня: не повторяющиеся элементы в таких списках - это реальная возможность несмотря на отсутствие в данном примере.
Роберт Мюил,
13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]
Mariy
источник
10
for item in my_list:
    if item.find("abc") != -1:
        print item
Rubycon
источник
3
Если вы собираетесь использовать этот подход, я думаю, что это более идиоматично, чем if 'abc' in itemиспользовать item.find('abc') == -1.
Уайетт Болдуин
4

Используйте __contains__()метод класса строки Pythons.

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")
Суровая Лоди
источник
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)
arun_munagala
источник
В 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
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

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

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утверждение более читабельно.

Юлиан
источник