Search code examples
pythoncomparecomparison

Compare many values and tell if neither of them equal


I'm working on a project and I need to compare some values between each other and tell if they DO NOT match. I have a list of thirteen lists and each of those have more than 500 values. All thirteen lists have the same length. I would like to find an index of the item in any of those thirteen lists.

However I tried to simplify the problem by making three lists and each of those contain four items.


list1 = [1, 2, 2, 2]
list2 = [1, 3, 2, 2]
list3 = [2, 4, 2, 2]

Blist = [list1, list2, list3]

for i in range(len(Blist)): #0, 1, 2
    for j in range(len(Blist)): #0, 1, 2
        if i == j:
            pass
        else:
            for k in range(len(list1)): #0, 1, 2, 3
                st = Blist[i][k] != Blist[j][k]
                print(st)

I could compare two lists at a time but I can't come up with the solution that would compare all items with the same index and return me a value of the index "ind" whose values don't match (when you compare list1[ind], list2[ind] and list3[ind]).

If there were only three lists I could write

for i in range(len(list1)):
    if (list1[i] != list2[i] and list1[i] != list3[i] and list2[i] != list3[i])
        print(i)

But I'd like to solve a problem even if it has hundreds of lists with hundreds of items.


Solution

  • For every index, create a set of values taking values from a single index for each nested list. As a set can't have duplicate elements, the length of the set should be equal to the total number of nested lists. Otherwise, there were duplicates, which means all the values of that index were not unique.

    values = [
        [1, 2, 2, 2, 5],
        [1, 3, 2, 2, 7],
        [2, 4, 2, 2, 1]
    ]
    
    n = len(values[0])  # Number of values in each nested list
    total = len(values)  # Total number of nested lists
    
    for i in range(n):
        s = {v[i] for v in values}
        if len(s) == total:
            print(i)
    

    Output:

    1
    4
    

    If you've understood the above approach, the code can be cut down using a somewhat functional approach. Basically 2 lines of python code. (written in multiple lines for improved readability).

    values = [
        [1, 2, 2, 2, 5],
        [1, 3, 2, 2, 7],
        [2, 4, 2, 2, 1]
    ]
    total = len(values)
    
    # Using a list comprehension to create a list with the unique indices
    unique_indices = [
        idx 
        for idx, s in enumerate(map(set, zip(*values))) 
        if len(s) == total
    ]
    print(unique_indices)
    

    Output:

    [1, 4]