-2

I am having trouble with set operation intersection.

Assume I have a list A = [0,1,2,3], and an integer B = 0. When I check if B in A:, I am getting of course True.

But when A and B are as default equal to None, than I can't do the intersection operation of A and B.

I am looking for a way to do following without getting an error:

A = None
B = None

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

Normally A is a python List and B is a string. But I need to set them to None as default, while they are arguments in my function; where they have to have a value of None.

PS: Getting True or False with the search algo. is not important. I just need to get True or False, so that I can arrange my error-raising.

oakca
  • 1,408
  • 1
  • 18
  • 40

6 Answers6

1

Why not try to check whether A or B is None itself?

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')
1

The easiest would be to set A = [] instead of A = None (it's a reasonable value for something that will be a list eventually).

If A is argument to your function, be careful you don't write

def f(A=[])

but, instead

def f(A=None):
    if A is None:
       A = []
blue_note
  • 27,712
  • 9
  • 72
  • 90
1

you could try:

if B in (A or []):

so if A is None it tests against empty list and yields False

if A is an empty list, it will also test against the rightmost operand of or but the result will be the same.

Larger scope: if you have default values as None in your function:

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

leave them as None, and change them in the function code so the default argument isn't mutable ("Least Astonishment" and the Mutable Default Argument).

if A is None:
   A = []
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

Continue using None as a default argument and then just set a to be the empty set set if it is None (I'm using lowercase argument names as per python convention):

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):
       ...
FHTMitchell
  • 11,793
  • 2
  • 35
  • 47
0
A = [None, 1, 2]
B = None

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

output

done
Nihal
  • 5,262
  • 7
  • 23
  • 41
0

The usual way one would go about None-initialized arguments in a function is to assign them to a sane default value at the start of said function. I use type annotation just to show which kind of values can be passed:

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')

The in keyword (if it is not part of a for-loop of course..) requires a python object as its right-side argument that offers a __contains__() function, which None doesn't.

Arne
  • 17,706
  • 5
  • 83
  • 99