Питання Чи містить Python рядок "містить" підстроковий метод?


Я шукаю a string.contains або string.indexof метод в Python.

Я хочу зробити:

if not somestring.contains("blah"):
   continue

2885
2017-08-09 02:52


походження




Відповіді:


Ви можете скористатись in оператор:

if "blah" not in somestring: 
    continue

4372
2017-08-09 02:56





Якщо це просто пошук підстроки, який ви можете використовувати string.find("substring").

Ви повинні бути трохи обережні з find, index, і in хоча, оскільки вони підрядні пошуки. Іншими словами, це:

s = "This be a string"
if s.find("is") == -1:
    print "No 'is' here!"
else:
    print "Found 'is' in the string."

Це буде друкувати Found 'is' in the string. Аналогічним чином if "is" in s: буде оцінювати до True. Це може або не може бути тим, що ви хочете.


460
2017-08-09 02:55



+1, щоб виділити отримані сторінки, що беруть участь у пошуках підрядів. очевидне рішення є if ' is ' in s: який повернеться False як очікується (можливо). - aaronasterling
@aaronasterling Очевидно це може бути, але не цілком правильно. Що робити, якщо у вас є пунктуація або це на початку чи в кінці? А як щодо капіталізації? Краще буде регістровий регістр для пошуку регістру \bis\b (кордони слів). - Bob
@JamieBull Ще раз, ви повинні розглянути, якщо ви хочете включити пунктуацію як роздільник для слова. Розщеплення матиме в основному такий же ефект, як і наївне рішення для перевірки ' is ', зокрема, це не спіймається This is, a comma' або 'It is.'. - Bob
@JamieBull: Я сильно сумніваюся, що будь-який справжній матеріал розділено з s.split(string.punctuation + string.whitespace) б розколовся навіть один раз; split не схоже на strip/rstrip/lstrip сімейство функцій, він розбивається тільки тоді, коли він бачить всі символи роздільника, суміжно, у тому точному порядку. Якщо ви хочете поділитись на класні символи, ви повернетесь до регулярних виразів (в який момент шукаєте r'\bis\b' без розщеплення - це простіший і швидший спосіб піти). - ShadowRanger
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split() - ОК, точка зору. Це зараз смішно ... - Jamie Bull


if needle in haystack: це звичайне використання, як каже @ Michael - він спирається на in оператор, більш читабельний і швидше, ніж виклик методу.

Якщо вам дійсно потрібен метод замість оператора (наприклад, щоб зробити якийсь дивний key= для дуже своєрідного ... »), це було б 'haystack'.__contains__. Але оскільки ваш приклад призначений для використання в if, Я здогадуюсь ви не дійсно означаєте що ви кажете ;-). Неправильна форма (ні читабельна, ні ефективна) безпосередньо використовувати спеціальні методи - вони призначені для використання замість операторів та вбудованих об'єктів, які їх делегують.


125
2017-08-09 03:19





В основному, ви хочете знайти підстроку в рядку в python. Існує два способи пошуку підстроки в рядку в Python.

Метод 1: in оператор

Ви можете використовувати Python's in Оператор перевірити підрядку. Це досить просто та інтуїтивно. Це повернеться True якщо підрядка була знайдена в рядку ще False.

>>> "King" in "King's landing"
True

>>> "Jon Snow" in "King's landing"
False

Метод 2: str.find() метод

Другий спосіб полягає у використанні str.find() метод Тут ми називаємо .find() метод на рядок, в якому потрібно знайти підрядку. Ми передаємо підрядку методу find () і перевіряємо його повернення значення. Якщо його значення відрізняється від -1, підрядка була знайдена в рядку, інакше це не було. Повертає значення - це індекс, де знайдено підстроку.

>>> some_string = "valar morghulis"

>>> some_string.find("morghulis")
6

>>> some_string.find("dohaeris")
-1

Я рекомендую вам скористатися першим методом, оскільки воно є більш пітонічним та інтуїтивно зрозумілим.


98
2018-05-26 17:46





Чи містить рядок Python спосіб підстрою?

Так, але в Python є оператор порівняння, який ви повинні використовувати замість цього, оскільки мова збирається використовувати її, і інші програмісти сподіваються, що ви її використовуватимете. Це ключове слово in, який використовується як оператор порівняння:

>>> 'foo' in '**foo**'
True

Протилежне (доповнення), про яке йдеться в оригінальному питанні, є not in:

>>> 'foo' not in '**foo**' # returns False
False

Це семантично таке ж, як і not 'foo' in '**foo**' але це набагато більш читабельно і явно передбачено на мові як покращення читабельності.

Уникайте використання __contains__, find, і index

Як і обіцяно, ось таке contains спосіб:

str.__contains__('**foo**', 'foo')

повертає True. Ви також можете викликати цю функцію з екземпляра суперструна:

'**foo**'.__contains__('foo')

Але ні. Методи, які починаються з підкреслень, вважаються семантично приватними. Єдина причина використання цього полягає в розширенні in і not in функціональність (наприклад, підкласування str):

class NoisyString(str):
    def __contains__(self, other):
        print('testing if "{0}" in "{1}"'.format(other, self))
        return super(NoisyString, self).__contains__(other)

ns = NoisyString('a string with a substring inside')

а зараз:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

Крім того, уникайте наступних рядкових методів:

>>> '**foo**'.index('foo')
2
>>> '**foo**'.find('foo')
2

>>> '**oo**'.find('foo')
-1
>>> '**oo**'.index('foo')

Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    '**oo**'.index('foo')
ValueError: substring not found

Інші мови можуть не мати способів безпосередньо перевіряти підрядки, і тому вам доведеться використовувати ці типи методів, але за допомогою Python набагато ефективніше використовувати inоператор порівняння

Порівняння результатів роботи

Ми можемо порівнювати різні способи досягнення однієї мети.

import timeit

def in_(s, other):
    return other in s

def contains(s, other):
    return s.__contains__(other)

def find(s, other):
    return s.find(other) != -1

def index(s, other):
    try:
        s.index(other)
    except ValueError:
        return False
    else:
        return True



perf_dict = {
'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
'__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
'__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}

І тепер ми бачимо, що використовуємо in набагато швидше, ніж інші. Менший час зробити еквівалентну операцію краще:

>>> perf_dict
{'in:True': 0.16450627865128808,
 'in:False': 0.1609668098178645,
 '__contains__:True': 0.24355481654697542,
 '__contains__:False': 0.24382793854783813,
 'find:True': 0.3067379407923454,
 'find:False': 0.29860888058124146,
 'index:True': 0.29647137792585454,
 'index:False': 0.5502287584545229}

90
2017-11-25 22:33



Чому слід уникати str.index і str.find? Як ще ви запропонуєте, щоб хтось знаходив індекс підрядка, а не просто, чи існує такий? (або ви мали на увазі уникати використання їх замість містять - так що не використовуйте s.find(ss) != -1 замість ss in s?) - coderforlife
Точно так, хоча наміри використання цих методів можуть бути краще вирішені елегантним використанням re модуль Я ще не знайшов використання для str.index або str.Зазначте себе в будь-якому коді, який я вже написав. - Aaron Hall♦


Ні, нічого немає string.contains(str) метод, але є in оператор:

if substring in someString:
    print "It's there!!!"

Ось більш складний робочий приклад:

# Print all files with dot in home directory
import commands
(st, output) = commands.getstatusoutput('ls -a ~')
print [f for f in output.split('\n') if '.' in f ]

61
2017-09-30 18:59



Не фанат синтаксичного аналізу ls, але я зрозумів, чому ви надали цей приклад. Тим не менш ... Було б досить побачити os.walk. - Josh Detwiler


in Строки та списки пітонів

Ось кілька корисних прикладів, які говорять самі про себе in спосіб:

"foo" in "foobar"
True

"foo" in "Foobar"
False

"foo" in "Foobar".lower()
True

"foo".capitalize() in "Foobar"
True

"foo" in ["bar", "foo", "foobar"]
True

"foo" in ["fo", "o", "foobar"]
False

Застереження Списки є ітерабельні, а також in Метод діє на iterables, а не тільки strings.


31
2018-04-28 18:52



Чи може список бути ітерабельним, щоб шукати будь-який список в одному рядку? Наприклад: ["bar", "foo", "foobar"] in "foof"? - CaffeinatedCoder
@CaffeinatedCoder, ні, для цього потрібна вкладена ітерація. Найкраще зроблено шляхом приєднання до списку з трубами "|". Join (["bar", "foo", "foobar"]) і складання regex з нього, а потім відповідність на "foof" - firelynx
Раніше я зрозумів, що це також можна зробити за допомогою генератора, що дозволило мені уникнути регулярного вираження. Спасибі за альтернативу, хоча! - CaffeinatedCoder
будь-який ([x в "foof" для x у ["bar", "foo", "foobar"]]) - Izaak Weiss
@IzaakWeiss Ваш один вкладиш працює, але це не дуже читабельно, і він вкладає ітерацію. Я порадив би це зробити - firelynx


Отже, очевидно, немає нічого подібного для векторного порівняння. Очевидним способом зробити це буде Python:

names = ['bob', 'john', 'mike']
any(st in 'bob and john' for st in names) 
>> True

any(st in 'mary and jane' for st in names) 
>> False

21
2017-07-17 13:19



Це тому, що є кілька мільйонів способів створення продукту з атомних змінних. Ви можете заповнити їх у вигляді кортежу, списку (які є формами Декартових продуктів і мають неявне замовлення), або вони можуть бути названі властивостями класу (без апріорного замовлення) або значків словника, або вони можуть бути файлами в каталог або інше. Кожного разу, коли ви можете однозначно ідентифікувати (iter або getitem) щось у контейнері або контексті, ви можете побачити цей контейнер у вигляді вектора та визначити на ньому біінні опери. en.wikipedia.org/wiki/... - Niriel
@Ufos, я думаю, що більш очевидний спосіб пітона для цього - використовувати any() або all(). Люблю : any([st in 'bob and john' for st in names]) >>> True - mgc
@ mgc, змінив його на any, Дякую. - Ufos
Вам не потрібні внутрішні квадратні дужки у будь-якому - python.org/dev/peps/pep-0289 - Eamonn M.R.


Інший спосіб визначити, чи містить рядок декілька символів чи ні з логічним значенням повернення (тобто True або "False"):

str1 = "This be a string"
find_this = "tr"
if find_this in str1:
    print find_this, " is been found in ", str1
else:
    print find_this, " is not found in ", str1

17
2017-07-28 12:32



Друк вже додає пробіли між рядками, але все-таки хороший приклад. - Xavier Arias Botargues
Скажіть, щоб шукати проти двох рядків find_that = "ng" чому це не працює: if (find_this or find_that) in str1: print "I found find_this or find_that" - yeliabsalohcin