Проверьте, содержится ли список A в списке B

У меня есть два списка, A и B, и я хотел бы проверить, содержится ли A в B. Под «содержащимся» я подразумеваю, что элементы A появляются в точно таком же порядке внутри B без каких-либо других элементов между ними. То, что я ищу, очень похоже на поведение A in B, если бы они были строками.

Некоторые элементы A будут повторяться. Мы можем предположить, что A будет короче, чем B.

На SO есть много ответов на похожие вопросы, но большинство отвечает на другой вопрос:

  • Является ли A элементом B? (Не мой вопрос: B — это плоский список, а не список списков.)
  • Все ли элементы A содержатся в B? (Не мой вопрос: я также беспокоюсь о порядке.)
  • Является ли A подсписком B? (Не мой вопрос: я не хочу знать, появляются ли элементы A в том же порядке в B, я хочу знать, появляются ли они точно, как они находятся где-то в B.)

Если бы операция была реализована как ключевое слово containedin, она бы вела себя так.

>>> [2, 3, 4] containedin [1, 2, 3, 4, 5]
True
>>> [2, 3, 4] containedin [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
False
>>> [2, 3, 4] containedin [5, 4, 3, 2, 1]
False
>>> [2, 2, 2] containedin [1, 2, 3, 4, 5]
False
>>> [2, 2, 2] containedin [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
False
>>> [2, 2, 2] containedin [1, 1, 1, 2, 2, 2, 3, 3, 3]
True

Есть ли краткий способ выполнить эту операцию в Python? Я пропустил какую-то важную терминологию, которая привела бы меня к ответу быстрее?

будет ли первый список всегда иметь длину 3

Talha Israr 19.01.2019 16:01

@TalhaIsrar Нет. Уточнил текст.

Daniel Standage 19.01.2019 16:04

элементы в списке всегда уникальны?

Cyzanfar 19.01.2019 16:05

@Cyzanfar Нет. Еще раз уточнил текст. :-)

Daniel Standage 19.01.2019 16:07

я оставил легкий и надеюсь, что это сработает

Talha Israr 19.01.2019 16:11

Эм... кто-то хочет объяснить свое отрицательное мнение? Я потратил много времени на то, чтобы четко сформулировать вопрос и ответить на просьбы о разъяснении.

Daniel Standage 19.01.2019 16:14

а у тебя 4 плюса?

Talha Israr 19.01.2019 16:16

Да, я не слишком беспокоюсь. Просто меня немного насторожило, так как это было второе голосование.

Daniel Standage 19.01.2019 16:16

Я думаю, что вы получаете отрицательные голоса, потому что вы, по-видимому, не пытались написать какой-либо код, чтобы сделать это самостоятельно.

martineau 19.01.2019 16:47
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
9
462
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Предполагая, что a всегда короче, чем b, вы можете сделать следующее.

 any(a == b[i:i+len(a)] for i in range(len(b)-len(a)+1))
Ответ принят как подходящий

Используйте any с нарезкой списка:

def contained_in(lst, sub):
    n = len(sub)
    return any(sub == lst[i:i+n] for i in range(len(lst)-n+1))

Или используйте join, чтобы соединить оба списка со строками и использовать оператор in:

def contained_in(lst, sub):
    return ','.join(map(str, sub)) in ','.join(map(str, lst))

использование:

>>> contained_in([1, 2, 3, 4, 5], [2, 3, 4])
True
>>> contained_in([1, 2, 2, 4, 5], [2, 3, 4])
False

У меня есть отношение любви/ненависти к этому второму предложению. Это самый хакерский, но, на мой взгляд, самый понятный с точки зрения намерений и синтаксиса, и очень лаконичный. +1

Daniel Standage 19.01.2019 16:19

Используйте эту функцию

Я старался не усложнять

def contains(list1,list2):

    str1 = ""
    for i in list1:
        str1+=str(i)

    str2 = ""
    for j in list2:
        str2+=str(j)

    if str1 in str2:
        return True

    else:
        return False

Надеюсь, что это работает :)

Учитывая, что вам нужно сохранить порядок:

def contains(sub_array, array):
    for i in range(len(array)-len(sub_array)+1):
        for j in range(len(sub_array)):
            if array[i+j] != sub_array[j]:
                break
        else:
            return i, i+len(sub_array)
    return False

Хороший. Даже дает вам индекс первого вхождения.

Daniel Standage 19.01.2019 16:15

Вы можете объединить 2 списка в две разные строки. Затем напишите функцию, которая проверяет, входит ли одна строка в другую.

def containedin(a, b):
 if b in a:
  return True
 return False`

Что-то вроде этого?

class myList(list):
    def in_other(self, other_list):
        for i in range(0, len(other_list)-len(self)):
            if other_list[i:i+len(self)] == self:
                return True
            else:
                continue

if __name__ == "__main__":

    x = myList([1, 2, 3])
    b = [0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]

    print(x.in_other(b))

многие люди опубликовали свои ответы. но я все равно хочу опубликовать свои усилия ;) это мой код:

def containedin(a,b):
    for j in range(len(b)-len(a)+1):
        if a==b[j:j+len(a)]:
            return True
    return False

print(containedin([2, 3, 4],[1, 2, 3, 4, 5]))
print(containedin([2, 3, 4],[1, 1, 2, 2, 3, 3, 4, 4, 5, 5]))
print(containedin([2, 3, 4],[5, 4, 3, 2, 1]))
print(containedin([2, 2, 2],[1, 2, 3, 4, 5]))
print(containedin([2, 2, 2],[1, 1, 1, 2, 2, 2, 3, 3, 3]))

это вывод: Истинный Ложь Ложь Ложь Истинный

Не нужно нарезать для каждого элемента:

def contains(seq, sub):
    sub_length = len(sub)
    sub_first = sub[0]
    return any(sub == seq[index:index+sub_length]
               for index, element in enumerate(seq)
               if element == sub_first)

Использование:

>>> seq = [1, 2, 3, 4, 5]
>>> sub = [2, 3, 4]

>>> contains(seq, sub)
True

Другие вопросы по теме