Search code examples
pythonarraysif-statement

If statement to check if an array is not in another array


I am currently doing an advent of coding problem link, and my solution involves checking if an array contains another array. however, the if statement doesn't work or something else is messing my code up.

string = " *really long thing, i deleted it* "
# example string = "v>"
location = [0,0]
been_to = [[0,0]]
string = list(string)

for i in string:
    if i == "v":
        #down
        location[1] -= 1
    elif i == "^":
        #up
        location[1] += 1
    elif i == ">":
        #right
        location[0] -= 1
    elif i == "<":
        #left
        location[0] += 1
    if location in been_to == False:
        been_to.append(location)
    #print(location)
print(been_to)

I have tried swapping the variables, moving a not or == false around, and generally trying anything that comes to mind. I still have no clue.


Solution

  • I think, the issue lies in the line if location in been_to == False:. This is not doing what you expect it to do.

    In Python, in is an operator that checks if a value is present in a sequence (like a list or a string). However, when you use in with a list of lists, it checks if the exact list is present in the outer list, not if a list with the same elements is present. The in operator is typically implemented using the contains() special method.

    So in your case, location is a list [x, y], and been_to is a list of lists [[x1, y1], [x2, y2], ...]. When you do location in been_to, it checks if the exact list [x, y] is present in been_to, not if a list with the same elements is present.

    This is because lists are not hashable, which means they cannot be used as keys in a dictionary or as elements in a set. Tuples, on the other hand, are hashable, which means they can be used as keys in a dictionary or as elements in a set. This is why using a tuple instead of a list for location solves the problem.

    You can use a tuple instead of a list for location, because tuples are hashable and can be compared for equality.

    string = "v>"
    # string = "^v^v>><<<>>"
    
    location = (0, 0)
    been_to = [(0, 0)]
    string = list(string)
    
    for i in string:
        if i == "v":
            # down
            location = (location[0], location[1] - 1)
        elif i == "^":
            # up
            location = (location[0], location[1] + 1)
        elif i == ">":
            # right
            location = (location[0] + 1, location[1])
        elif i == "<":
            # left
            location = (location[0] - 1, location[1])
        
        # Check if the location is already in been_to
        if location not in been_to:
            been_to.append(location)
    
    print(been_to)
    print(f"Total houses visited at least once: {len(been_to)}")
    
    >> [(0, 0), (0, -1), (1, -1)]
    >> Total houses visited at least once: 3
    

    This output represents the list of houses visited at least once, with each house represented by its coordinates (x, y). The total number of houses visited at least once is also printed.