def p3(x,y,ls2):
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
c=0
break
else:
c=1
if c==0:
return False
else:
return True
Even I have assigned c in the same function, it still displays "local variable 'c' referenced before assignment"
CodePudding user response:
As the comment by Suraj S says, the problem is if ls2
is an empty list (iterable). Even if that were not a problem, c
is a local variable inside the for
loop and even though Python allows accessing it outside its scope, it is not a good practice to do so. So it is correct to default initialize it first before running the loop. You can default it to 0 or 1 depending on your use case.
Also, practice Boolean Zen. Don't make redundant checks with booleans. It is better to use True
and False
instead of 0 and 1.
def p3(x,y,ls2):
c = True # default
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
c = False
break
# no need for else at all
return c
Even better:
def p3(x,y,ls2):
for i in ls2:
if abs(i[0]-x)==abs(i[1]-y):
return False
# no need for else at all
return True
CodePudding user response:
If I understand correctly your function, you could simplify it to the following:
def p3(x, y, ls2):
# if no list or list is empty
if not ls2: # the condition could be more convoluted if needed
return 'invalid input' # or return boolean depending on use case
for i in ls2:
# if condition is matched return immediately
if abs(i[0]-x)==abs(i[1]-y):
return False
# the condition was not matched in loop, return default True
return True
You could even simplify more using all
that will stop prematurely if the condition is met:
def p3(x, y, ls2):
# if no list or list is empty
if not ls2: # the condition could be more convoluted if needed
return 'invalid input' # or return boolean depending on use case
return all(abs(i[0]-x)!=abs(i[1]-y) for i in ls2)
# or: return not any(abs(i[0]-x)==abs(i[1]-y) for i in ls2)
CodePudding user response:
In general, if you instantiate a variable (namely c
) inside of a for loop, it's best not to use that variable outside of that for loop.
The practical reason for this is that you can't be sure that for loop will run and so the variable might not get instantiated. The more high-level reason is to maintain a sense of scope in your code, or "what happens in the for loop, stays in the for loop", if you will.
So in your case, I would recommend instantiating c
with a 'default' value (depending on what your logic is) before the for loop starts, so that even if the for loop runs 0 times, c still has a value.
Alternatively, this entire function could be implemented as
def p3(x, y, ls2):
return not any([abs(i[0]-x)==abs(i[1]-y) for i in ls2])