Я хочу проверить, присутствует ли какой-либо из объектов в одном списке в другом списке. Я могу сделать это просто с кодом ниже, но я подозреваю, что могла бы быть библиотечная функция, чтобы сделать это. В противном случае есть ли больше pythonic метода достижения того же результата.
In [78]: a = [1, 2, 3, 4, 5]
In [79]: b = [8, 7, 6]
In [80]: c = [8, 7, 6, 5]
In [81]: def lists_overlap(a, b):
....: for i in a:
....: if i in b:
....: return True
....: return False
....:
In [82]: lists_overlap(a, b)
Out[82]: False
In [83]: lists_overlap(a, c)
Out[83]: True
In [84]: def lists_overlap2(a, b):
....: return len(set(a).intersection(set(b))) > 0
....:
Вы также можете использовать any
с пониманием списка:
any([item in a for item in b])
def lists_overlap(a, b):
sb = set(b)
return any(el in sb for el in a)
Это асимптотически оптимально (наихудший случай O (n + m)) и может быть лучше, чем подход пересечения из-за короткого замыкания любого
.
Например:
lists_overlap([3,4,5], [1,2,3])
вернет True, как только он достигнет 3 в sb
РЕДАКТИРОВАТЬ: Другой вариант (с благодарностью Дэйву Кирби):
def lists_overlap(a, b):
sb = set(b)
return any(itertools.imap(sb.__contains__, a))
Это зависит от imap
] итератор, который реализован на C, а не понимание генератора. Он также использует sb .__ contains __
в качестве функции сопоставления. Я не знаю, насколько это влияет на производительность. Это все равно будет короткое замыкание.
Вы можете использовать встроенную функцию any /w в качестве выражения-генератора:
def list_overlap(a,b):
return any(i for i in a if i in b)
Как отметили Джон и Ли, это дает неправильный результат, когда для каждого i, разделяемого двумя списками, bool(i) == False. Должно быть так:
return any(i in b for i in a)
def lists_overlap3(a, b):
return bool(set(a) & set(b))
Примечание: вышесказанное предполагает, что в качестве ответа вы хотите использовать логическое значение. Если все, что вам нужно, это выражение для использования в операторе if
, просто используйте if set (a) & set (b):