Reputation: 129
I'm trying to use recursion to return the dot product of two lists, and I'm trying to account for the situation in which I get two lists of different length: I return 0. However, when I try to check for that condition, I get the error: unsupported operand type(s) for &: 'list' and 'list'. Why can't I use the '&' operand for two lists in Python?
def dot(L, K):
if L+K == []:
return 0
elif L == [] & K != []:
return 0
elif K == [] & L != []:
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
Upvotes: 0
Views: 194
Reputation: 53
If you check out python's Operator Precedence you will see that &
has lower precedence than ==
and and
This means you are doing the following:
if (L == ([] & K)) != []:
...
As suggested by Tuan333 you should be using and
.
def dot(L, K):
if L+K == []:
return 0
elif L == [] and K != []:
return 0
elif K == [] and L != []:
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
However if you wanted to use &
(which is the Binary AND, and isn't the same thing) you could just use ()
to force precedence
def dot(L, K):
if L+K == []:
return 0
elif (L == []) & (K != []):
return 0
elif (K == []) & (L != []):
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
If you're curious why &
is likely not what you want read on:
AND
takes two values, converts them to Booleans (True
or False
) and check that both are True
&
) takes two values, converts them to a Number-like value, then performs an operation on their bitsHere is how I would implement this function
def dot(L, K):
if len(L) != len(K):
# Ensure the lists are the same length
raise ValueError('Can not perform dot product on two differently sized lists')
elif len(L) + len(K) == 0:
# See if we've reached the base case
return 0
else:
# Recurse doing dot product
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
print(dot([6, 2, 6], [5, 1]))
Upvotes: 0
Reputation: 10433
I would probably do something like this:
def dot(L, K):
if L + K == [] or len(L) != len(K): # this only needs to be checked once
return 0
return dot_recurse(L, K)
def dot_recurse(L, K):
if len(L) > 0:
return L[-1] * K[-1] + dot_recurse(L[:-1], K[:-1])
else:
return 0;
Upvotes: 1
Reputation: 1
Your code is a bit more complicated than it really needs to be. It is not possible to take the dot product of two vectors which are not the same size. There are a couple of ways to deal with receiving vectors of different sizes.
1) Lop off the remaining unused numbers from the larger vector. Below is a modified version of your function. I changed it to only require one check for if either of the vectors is empty (there is no need to check this in multiple ways), and also changed it to start from the beginning of the vectors instead of the end. Was there a particular reason you started from the end?
def dot(L, K):
if(L == [] or K == []):
return 0
else:
return L[0] + K[0] + dot(L[1:], K[1:])
While this option works, it does not give the user any indication that they made a mistake in attempting to dot product two different sized vectors.
2) Give the user an error upon receiving two different sized vectors.
def dot(L, K):
if(len(L) != len(K)):
print('Vector sizes do not match, please pass two same-sized vectors')
return 0 #not sure exactly how you are wanting to do error handling here.
elif(L == [] or K == []):
return 0
else:
return L[0] + K[0] + dot(L[1:], K[1:])
Upvotes: 0
Reputation: 32095
def dot(L, K):
if len(L)!=len(K): # return 0 before the first recursion
return 0
elif not L: # test if L is [] - previous test implies K is [] so no need to retest
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
Upvotes: 0