Home > Back-end >  How to compare a list with uneven list of lists
How to compare a list with uneven list of lists

Time:10-15

summary

Comparing two lists: A = [2,3] and B = [[2],[1,2]], the goal if to find the elements of A not present in B: here: [3].

question

I am trying compare two lists and output the unique number from A.

A = [2,3]
B = [[2],[1,2]]
for x in range(len(A)):
    for y in range(len(B)):
        for z in range(len(B)):
            if A[x] not in B[y][z]:
                return x

The expected answer is 3, however I am getting an error from running this code. Any help is appreciated :)

CodePudding user response:

Aside from your loop issue that @RocketHazmat nicely fixed, the multi-loop approach is very inefficient a you need to compare all elements of B with all elements of A.

Rather use set difference:

from itertools import chain
set(A).difference(chain.from_iterable(B))

output: {3}

shorter and faster variant:

nice shorter variant from @DaniMasejo: set(A).difference(*B)

This variant is ~2 times faster on large datasets (here random dataset of 1000 items):

import random
A = np.random.randint(0,1000, size=1000).tolist()
B = [np.random.randint(1,1000, size=random.randint(1,100)).tolist() for i in range(1000)]

output:

# set(A).difference(*B)
638 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# set(A).difference(chain.from_iterable(B))
1.16 ms ± 2.72 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

CodePudding user response:

I'd suggest flattening list B and then using set.difference to find unique elements in set A.

A: set[int] = {2, 3}
B: list[list[int]] = [[2], [1, 2]]

B_flat: set[int] = {num for b_list in B for num in b_list}

assert A.difference(B_flat) == {3}

Note: if you are using an earlier Python version than 3.9, I suggest importing and using Set and List from the typing module instead. For example, List[List[int]].

Alternatively, as mentioned in comments below, I did not think of this either but the above can be simplified even further - there is no need to flatten the list B at all, as you can use list unpacking via the * operator instead:

A: list[int] = [2, 3]
B: list[list[int]] = [[2], [1, 2]]

assert set(A).difference(*B) == {3}

CodePudding user response:

Your 3rd for loop is looping over the wrong thing.

It should be

for z in range(len(B[y])):

CodePudding user response:

You could consider flattening list B and then find the unique elements:

A = [2, 3]
B = [[2], [1,2]]

flatB = [item for sublist in B for item in sublist]
output = [i for i in A if i not in flatB]

>>> output
[3]
  • Related