Если ваши списки не могут содержать дубликаты, и вы не заботитесь о порядке, то вы должны использовать наборы вместо списков (кстати, они называются списками, а не массивами). Тогда то, что вы хотите, быстро и просто реализовать:
>>> set1 = set(["abc", "def", "ghi", "jkl"])
>>> set2 = set(["abc", "ghi", "456", "789"])
>>> set2 - set1
set(['456', '789'])
Если list2 может содержать дубликаты или порядок имеет значение, вы все равно можете сделать list1 набором для ускорения поиска:
>>> list1 = ["abc", "def", "ghi", "jkl"]
>>> list2 = ["abc", "ghi", "456", "789"]
>>> set1 = set(list1)
>>> [a for a in list2 if a not in set1]
['456', '789']
Обратите внимание, что для этого требуется, чтобы элементы были хэшируемыми, но выполнялись в течение времени, близкого к O (n).
Если элементы не могут быть хешируемыми, но их можно заказать, вы можете отсортировать list1 и использовать двоичный поиск, чтобы найти элементы в нем. Это дает O (n log (n)) время.
Если ваши элементы не являются ни хешируемыми, ни упорядочиваемыми, вам придется прибегнуть к медленному O (n * n) простому линейному поиску для каждого элемента.