Saranya Raja
Saranya Raja

Reputation: 21

Python: else statement returns True, though it's mentioned to return False

I'm writing a function that validates two lists passed as arguments and returns True if the structure of both the lists are same and returns False otherwise.

Tried with print statements at multiple places of the code and see no issue. Else statement prints "False" as expected, for different structure lists, but strangely function returns True, though it should return False.

def same_structure_as(original,other):
    if isinstance(original, list) and isinstance(other, list):
        if len(original) == len(other):
            for el in original:
                if isinstance(el, list):
                    orig_new = original[original.index(el)]
                    other_new = other[original.index(el)]
                    same_structure_as(orig_new,other_new)
            return True
        else:
            return False
    else:
        print("False")
        return False

same_structure_as([1,[1,1]],[[2,2],2])

Since the structure of both the input lists are different, the code should return False. print statement correctly prints "False", but returns "True" even though i gave "return False"

Upvotes: 1

Views: 481

Answers (2)

Reedinationer
Reedinationer

Reputation: 5774

The easiest way to fix it is to simply return your recursive function (which I'm sure is what your intent was):

def same_structure_as(original, other):
    if isinstance(original, list) and isinstance(other, list):
        if len(original) == len(other):
            for el in original:
                if isinstance(el, list):
                    orig_new = original[original.index(el)]
                    other_new = other[original.index(el)]
                    return same_structure_as(orig_new, other_new) # just add a return here
            return True
        else:
            return False
    else:
        print("False")
        return False

print(same_structure_as([1,[1,1]],[[2,2],2]))

Yields the correct:

False

False

I drew a diagram explaining this situation on a previous post

Upvotes: 1

Patrick Artner
Patrick Artner

Reputation: 51623

You are not returning False if an inner list has a mismatch:

def same_structure_as(original,other):
    if isinstance(original, list) and isinstance(other, list):
        if len(original) == len(other):
            for el in original:
                if isinstance(el, list):
                    orig_new = original[original.index(el)]
                    other_new = other[original.index(el)]
                    same_structure_as(orig_new,other_new) # here - the result is ignored
            return True
        else:
            return False
    else:
        print("False")
        return False

You need

def same_structure_as(original,other):
    if isinstance(original, list) and isinstance(other, list):
        if len(original) == len(other):
            for el in original:
                if isinstance(el, list):
                    orig_new = original[original.index(el)]
                    other_new = other[original.index(el)]
                    if not same_structure_as(orig_new,other_new): # early exit if not same 
                        return False
                     # else continue testing (no else needed - simply not return anything)
            return True
        else:
            return False
    else:
        print("False")
        return False

elsewise you "detect/print" wrongness but never act upon.

Upvotes: 4

Related Questions