Проверка, следует ли за элементом непосредственно другой элемент в списке (python)

#python #list #indexing #while-loop

#python #Список #индексирование #цикл while

Вопрос:

Я хочу проверить, следует ли за элементом непосредственно другой элемент в списке. Однако мой код работает примерно так: скажем, если я хочу посмотреть, следует ли за «1» «3», это не сработает, если список идет [1, 1, 3] . Я пытался поиграть с циклами while, но на самом деле это не сработало. Вот мой код на данный момент:

 def contains(lst, a, b):
x = 1
y = 0
for _ in lst:
    while (lst.index(a) y) == (lst.index(a) x):
        x  = 1
        y  = 1
    else:
        if lst.index(b) == (lst.index(a)   x):
            return True
        else:
            return False
  

Мой план состоит в том, чтобы создать цикл while, который проверяет, имеет ли элемент после «a» то же значение, что и «a», и когда значения больше не совпадают, он сравнивает последнее значение цикла со следующим и проверяет, равно ли оно «b». Не могу понять, как заставить его работать.

Комментарии:

1. Обычно вы бы заархивировали список с самим собой и протестировали кортежи: any(a == b for a, b in zip(some_list, some_list[1:]))

Ответ №1:

Я думаю, что ваши требования не определены четко. Для аргументов 1 и 3 должен ли [1, 2, 3] возвращать True? например, должен ли следующий номер сразу следовать за другим или он может появиться позже в списке?

Вот моя попытка сделать что-то, что проверяет b , появляется ли сразу после a :

 def contains(lst, a, b):
    # Iterate over all entries in the list
    for i, value in enumerate(lst):
        # Check if this entry matches `a` and is not the final entry
        if value == a and i < len(lst):
            # Check if the next entry matches `b`
            if lst[i 1] == b:
                return True
    return False      
  

И если b появляется в любом месте списка после a :

 def contains(lst, a, b):
    # Iterate over all entries in the list
    for i, ivalue in enumerate(lst):
        # Check if this entry matches `a`
        if ivalue == a and i < len(lst):
            # Now iterate through the rest of the list:
            for jvalue in lst[i 1:]:
                # Check if this entry matches 'b':
                    if jvalue == b:
                        return True
            # Can break this loop after finding first instance of `a`
            break
    return False      
  

Комментарии:

1. Извините, если я не понял. С «непосредственно» я имел в виду, что между «a» и «b» не может быть элемента, и что «b» появляется сразу после «a». Итак, ваш первый код верен, спасибо!

Ответ №2:

Помимо опции, упомянутой @MarkMeyer в комментариях, вы можете использовать регулярное выражение с предварительным утверждением.

 import re

def contains(data, a, b):
    pattern = re.compile(r"{}(?={})".format(a, b))
    if isinstance(data, list):
        data = "".join(str(s) for s in data)
    maybe_found = pattern.search(data)
    if maybe_found:
        return True
    return False

contains(data, 1, 3)
>> True

contains(data, 1, 4)
>> False

contains(data, 1, 1)
>> True