Установить пересечение с None

У меня проблемы с пересечением заданных операций.

Предположим, у меня есть список A = [0,1,2,3] и целое число B = 0. Когда я проверяю if B in A:, я получаю, конечно, True.

Но когда A и B по умолчанию равны None, я не могу выполнить операцию пересечения A и B.

Я ищу способ сделать следующее без получения ошибки:

A = None
B = None

if B in A:
    raise KeyError('B in A')

Обычно A — это список Python, а B — строка. Но мне нужно установить их на None по умолчанию, пока они являются аргументами в моей функции; где они должны иметь значение None.

PS: Получение True или False с алгоритмом поиска. не важно. Мне просто нужно получить True или False, чтобы я мог упорядочить свои ошибки.


person oakca    schedule 29.08.2018    source источник
comment
Вы пробовали A=[None]?   -  person Chillie    schedule 29.08.2018
comment
Разве вы не можете установить A = set() if not A else A в начале своей функции?   -  person Arne    schedule 29.08.2018
comment
Они должны быть по умолчанию Нет   -  person oakca    schedule 29.08.2018
comment
Почему вы не можете просто проверить, являются ли они None?   -  person khelwood    schedule 29.08.2018
comment
Потому что дело в том, чтобы проверить, есть ли B в A, и они должны быть None по умолчанию в моем аргументе функций.   -  person oakca    schedule 29.08.2018
comment
ты не можешь if B in (A or [])   -  person Jean-François Fabre    schedule 29.08.2018
comment
Я бы порекомендовал использовать значение по умолчанию для A, так как обычно вы не хотите, чтобы в вашем наборе аргументов изменялось: def fun(A=None, B=None): если A равно None: A=[] return B в A   -  person E.Serra    schedule 29.08.2018


Ответы (6)


Проще всего было бы установить A = [] вместо A = None (это разумное значение для чего-то, что в конечном итоге станет списком).

Если A является аргументом вашей функции, будьте осторожны, чтобы не написать

def f(A=[])

но вместо этого

def f(A=None):
    if A is None:
       A = []
person blue_note    schedule 29.08.2018
comment
Выглядит красиво, могу я также сделать A.isdisjoint(B)? - person oakca; 29.08.2018
comment
@Icedkk нет, это установленный метод. Вы сказали, что A — это список. Если вам нужен набор, почему бы не использовать объект набора. A = set()? - person FHTMitchell; 29.08.2018
comment
будьте осторожны: ОП сказал, что он получает None из параметров. Не используйте изменяемые значения по умолчанию в параметрах. - person Jean-François Fabre; 29.08.2018
comment
@FHTMitchell, вы правы, после этого он создает набор ... Во всяком случае, что-то похожее на isdisjoint () для списка? - person oakca; 29.08.2018
comment
Но зачем вообще использовать list, если вы собираетесь превратить его в набор, используйте набор с самого начала. set(A).isdisjoint(...) будет работать, но не очень эффективно. - person FHTMitchell; 29.08.2018
comment
Я просто хотел знать, есть ли такая функция, как isdisjoint, также для списков, но ty. - person oakca; 29.08.2018

Почему бы не попробовать проверить, является ли A или B самим None?

A = None
B = None

if None not in [A, B] and B in A:
    print('B in A')
else:
    print('B or A is None, or B is not in A')
person SampleText2k77    schedule 29.08.2018

вы можете попробовать:

if B in (A or []):

поэтому, если A равно None, он проверяет пустой список и дает False

если A является пустым списком, он также будет проверять крайний правый операнд or, но результат будет таким же.

Большая область: если у вас есть значения по умолчанию как None в вашей функции:

def foo(A=None,B=None):

оставьте их как None и измените их в коде функции, чтобы аргумент по умолчанию не изменялся (Наименьшее изумление и изменяемый аргумент по умолчанию).

if A is None:
   A = []
person Jean-François Fabre    schedule 29.08.2018

Продолжайте использовать None в качестве аргумента по умолчанию, а затем просто установите a как пустой набор set, если это None (я использую имена аргументов в нижнем регистре в соответствии с соглашением Python):

def f(a=None, b=None):
   if a is None:
       a = set()

    if b in a:
        raise KeyError('b in a')

    if a.isdisjoint(other_set):
       ...
person FHTMitchell    schedule 29.08.2018

A = [None, 1, 2]
B = None

if B in A: # where A should be a list, it should be iterable
    print('done')

выход

done
person Nihal    schedule 29.08.2018

Обычный способ использования None-инициализированных аргументов в функции — присвоить им разумное значение по умолчанию в начале указанной функции. Я использую аннотацию типа только для того, чтобы показать, какие значения можно передавать:

from typing import List, Optional

def check_intersect(A: Optional[List[str]] = None, B: Optional[str] = None):
    if A is None:
        A = []
    if B in A:  # this can't fail any more 
        raise KeyError('B in A')

Ключевое слово in (если оно, конечно, не является частью цикла for..) требует объекта python в качестве правого аргумента, который предлагает функцию __contains__(), которой нет в None.

person Arne    schedule 29.08.2018