Несколько параметров для функции __contains__

1

Возможно ли передать функцию "__ содержит __" в списке более одного параметра? Я хотел бы проверить, существует ли хотя бы один из элементов, которые есть в списке, в другом списке.

Например: [0,1,4,8,87,6,4,7,5, 'а', 'е', 'э', 'фа', 'VZ']

Я хотел бы проверить, включены ли в этот список один из элементов (8,5, 'f').

Как я могу это сделать?

Теги:
contains

3 ответа

2
Лучший ответ

Вы можете использовать наборы:

list1 = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
tuple1 = (8,5,'f')

def my_contains(first, second):
    return bool(set(first).intersection(second))

my_contains(list1, tuple1) # True
my_contains(list1, [1]) # True
my_contains(list1, (125,178,999)) # False
  • 2
    +1, хорошее использование набора. intersection () может взять вторую итерацию напрямую. Вы можете произвести True / False, просто вызвав bool (someset). return bool(set(first).intersection(second))
  • 1
    Один ключевой момент, на который следует обратить внимание, заключается в том, что подходы, основанные на множествах, работают, только если все используемые значения являются хешируемыми. Если это не может быть гарантировано, тогда необходимо принять итеративное решение (вероятно, с использованием any встроенной функции).
7

AFAIK, __contains__ принимает только один аргумент и его нельзя изменить.

Однако вы можете сделать следующее, чтобы получить желаемый результат:

>>> a = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
>>> any(map(lambda x: x in a, (8,5,'f')))
True

или

>>> from functools import partial
>>> from operator import contains
>>> f = partial(contains, a)
>>> any(map(f, (2,3)))
False
  • 1
    +1 за использование любого, тоже приятно продемонстрировать частичное. Более питонно использовать генератор вместо map + lambda.
  • 1
    Как отметил Кевпи, первое предложение будет значительно чище, чем any(x in a for x in (8,5,'f')) . Всякий раз, когда лямбда передается в качестве первого аргумента для map это сильный намек на то, что вместо этого следует использовать выражение понимания или генератора.
3

Используйте встроенный set.

>>> l =  [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
>>> s = (8,5,'f')
>>> bool(set(s) & set(l))
True

Устанавливать методы также будут принимать итераторы в качестве аргументов, избегая создания набора.

Самый краткий:

2.6 предоставляет set.isdisjoint(другое), который, вероятно, оптимизирован для возврата, как только будет найден общий элемент.

>>> not set(l).isdisjoint(s)
True

Если вы хотите выполнить цикл:

>>> any((val in s) for val in l)
True

Ещё вопросы

Сообщество Overcoder
Наверх
Меню