2

I'm looking for a method that would allow me to check what elements are missing when comparing 2 lists. A lot like in this thread but I want to write this in NumPy Python.

Complement of Two Lists?

import numpy as np

numbers = np.array([1,2,3,4,5,6,7,8,9])
A = np.array([2,5,6,9])

def listComplementElements(list1, list2):

    storeResults = []

    for i in list1:
        for j in list2:

            if i != j:
                #write to storeResults if 2 numbers are different
                storeResults.append(i)
            else:
                #if numebrs are equal break out of the loop
                break

    return storeResults            

result = listComplementElements(numbers, A)
print(result) #expected result [1,3,4,7,8]

At the moment the output looks like this: [1, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9]

What am I doing wrong?

michal-ko
  • 397
  • 4
  • 12
  • 1
    @Prune, that's an interesting duplicate choice, might I suggest: https://stackoverflow.com/questions/42273686/create-a-complement-of-list-preserving-duplicate-values or https://stackoverflow.com/questions/6486450/python-compute-list-difference – Nick is tired Mar 20 '19 at 17:02
  • @NickA: much better; thanks. I added it to the list of dups. – Prune Mar 20 '19 at 17:04

2 Answers2

12

This will give you the complement of the two arrays:

list(set(numbers) - set(A))
[1, 3, 4, 7, 8]

If you have duplicate values that you want to preserve, you can use the following:

from collections import Counter

c1 = Counter(numbers)
c2 = Counter(A)

diff = c1 - c2
print(list(diff.elements()))
Nathaniel
  • 3,230
  • 11
  • 18
  • That is true. A different method would be required if you want to preserve duplicate values. I have updated my answer to include one. – Nathaniel Mar 20 '19 at 17:03
1

This is what you were going for:

import numpy as np

numbers = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
A = np.array([2, 5, 6, 9])

def listComplementElements(list1, list2):
    storeResults = []

    for num in list1:
        if num not in list2: # this will essentially iterate your list behind the scenes
            storeResults.append(num)

    return storeResults

result = listComplementElements(numbers, A)
print(result) #expected result [1,3,4,7,8]

Prints:

[1, 3, 4, 7, 8]

You should only have one loop and then say if not in to evaluate the relationship with the second list. Otherwise you will loop unnecessarily and like you saw, it will output the result many times! Furthermore, using operators like is in or not in makes your code more readable than trying to comprehend many nested loops :)

Reedinationer
  • 5,661
  • 1
  • 12
  • 33