Как проверить, содержит ли строка элемент из списка в Python


218

У меня есть что-то вроде этого:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

Мне интересно, что было бы более элегантным способом сделать это в Python (без использования цикла for)? Я думал о чем-то вроде этого (например, из C / C ++), но это не сработало:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

Редактировать: я вынужден объяснить, как это отличается от вопроса ниже, который помечен как потенциальный дубликат (так что, я думаю, он не закрывается).

Разница в том, что я хотел проверить, является ли строка частью какого-либо списка строк, тогда как другой вопрос - проверить, является ли строка из списка строк подстрокой другой строки. Похоже, но не совсем то же самое, и семантика имеет значение, когда вы ищете ответ онлайн ИМХО. Эти два вопроса на самом деле направлены на решение противоположной проблемы друг друга. Решение для обоих оказывается одинаковым, хотя.


4
Возможный дубликат проверки
— GingerPlusPlus

Ответы:


423

Вместе с генератором используйте генератор any, который замыкает первый True:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

РЕДАКТИРОВАТЬ: Я вижу, что этот ответ был принят OP. Хотя мое решение может быть «достаточно хорошим» решением его конкретной проблемы, и это хороший общий способ проверить, найдены ли какие-либо строки в списке в другой строке, имейте в виду, что это все, что делает это решение. Неважно, где находится строка, например, в конце строки . Если это важно, как это часто бывает с URL-адресами, вам следует обратиться к ответу @Wladimir Palant, иначе вы рискуете получить ложные срабатывания.


1
это было именно то, что я искал. в моем случае не имеет значения, где в строке находится расширение. спасибо
— pootzko

Отличное предложение. Используя этот пример, вот как я проверяю, совпадает ли какой-либо из аргументов с хорошо известными флагами помощи: any ([x.lower () в ['-?', '- h', '- help', '/ h '] для x в sys.argv [1:]])
— AX Labs

@ AX-Labs, использующие составления списков внутри any, сведут на нет некоторые из возможных выгод, которые дает короткое замыкание, потому что весь список должен быть построен в каждом случае. Если вы используете выражение без квадратных скобок ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])), x.lower() in [...]часть будет оцениваться только до тех пор, пока не будет найдено значение True.
— Лауриц В. Таулов

5
И если я хочу знать, что такое ext, когда any () возвращает True?
— Питер Сенна

@PeterSenna: any()будет возвращать только true или false , но см. Приведенный ниже ответ @psun о понимании списка с этой модификацией:print [extension for extension in extensionsToCheck if(extension in url_string)]
— Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
этот умный - я не знал, что кортежи могут это делать !, но он работает только тогда, когда ваша подстрока привязана к одному концу строки.
— Даннид

3
Круто. Я просто хотел бы, чтобы было что-то вроде «содержит», а не только начиналось с или заканчивалось
— BrDaHa

@BrDaHa вы можете использовать «в» для содержит. if 'string' в списке:
— Шехар Саманта

@ShekharSamanta, конечно, но это не решает проблему проверки, есть ли одна из нескольких вещей в строке, то есть о чем был первоначальный вопрос.
— BrDaHa

Да, в этом случае мы можем использовать: если есть (элемент в string.split ('any delmiter') для элемента в списке) и для строки, если есть (элемент в строке для элемента в списке)
— Шекхар Саманта

21

Лучше разобрать URL-адрес правильно - таким образом, вы можете справиться http://.../file.doc?fooи http://.../foo.doc/file.exeправильно.

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

Используйте списки, если вы хотите однострочное решение. Следующий код возвращает список, содержащий строку url_string, если он имеет расширения .doc, .pdf и .xls, или возвращает пустой список, если он не содержит расширения.

print [url_string for extension in extensionsToCheck if(extension in url_string)]

ПРИМЕЧАНИЕ: это только для проверки, если оно содержит или нет, и бесполезно, когда нужно извлечь точное слово, соответствующее расширениям.


Это более читабельно, чем anyрешение, на мой взгляд, это одно из лучших возможных решений этого вопроса.
— Дмитрий Верхотуров

По any()моему мнению, этот вариант превосходит решение, потому что его можно изменить, чтобы он также возвращал определенное значение соответствия, например так: print [extension for extension in extensionsToCheck if(extension in url_string)](см. Мой ответ для получения дополнительной информации и того, как извлечь соответствующее слово, а также шаблон из url_string)
— Даннид

2

Проверьте, соответствует ли это регулярному выражению:

'(\.pdf$|\.doc$|\.xls$)'

Примечание: если ваши расширения находятся не в конце URL, удалите $символы, но это немного ослабляет его


1
Это URL, что если в нем есть строка запроса?
— Владимир Палант

import re resese (pattern, your_string)
— juankysmith

хотя этот ответ работает для указанного случая, он не является масштабируемым или универсальным. вам понадобится длинное регулярное выражение для каждого шаблона, который вы хотите сопоставить.
— Даннид

1

Это вариант ответа о понимании списка, заданного @psun.

Переключая выходное значение, вы можете фактически извлечь шаблон сопоставления из списка (что невозможно при any()подходе @ Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

[ '.Doc'] `

Кроме того, вы можете вставить регулярное выражение, если вы хотите собрать дополнительную информацию, как только сопоставленный шаблон известен (это может быть полезно, когда список разрешенных шаблонов слишком длинный для записи в один шаблон регулярного выражения)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

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