Home > front end >  Why does it display "local variable referenced before assignment" even I have assigned it
Why does it display "local variable referenced before assignment" even I have assigned it

Time:11-12

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])
  • Related