Reputation: 59
So I have two lists and one main list. The elements in the main list should be removed if they are present in either of the other two lists.
Example:
s1 = [1,2,3,4,7]
s2 = [3,4,5,6,20]
mainlist = [6,7,8,9,10,11,12,13,14,15]
So, as the mainList contains the elements 6 and 7 which are also present in either s1 or s2, they should be removed and the result should be like the following.
resultList = [8,9,10,11,12,13,14,15]
My code:
for j in mainlist[:]:
if j in s1 or j in s2:
mainlist.remove(j)
Is there anyway without using the for loop? I need an efficient way to reduce time complexity. Thank you !
Upvotes: 3
Views: 79
Reputation: 189
You can convert s1
and s2
to dict
s1 = {i:i for i in s1}
s2 = {i:i for i in s2}
mainlist = [i for i in mainlist if i not in s1 or i not in s2]
You would lose some time with converting lists to dict, but since python dictionary is basically hash table, then search complexity is O(1)
and not O(n)
like with lists.
So in the end it would be not O(n^2)
, but O(n)
or something like that.
Let me know if you try this.
Upvotes: 1
Reputation: 7214
You can also use counter to perform this:
from collections import Counter
print(list(Counter(mainlist) - Counter(s1) - Counter(s2)))
Out[309]: [8, 9, 10, 11, 12, 13, 14, 15]
Upvotes: 0
Reputation: 1406
Try this:
mainlist = list(set(mainlist) - (set(s1)|set(s2)))
Here I am assuming that none of the lists have repeated elements.
You can time and compare it from other methods.
time_idx = time()
result = [x for x in mainlist if x not in s1 and x not in s2]
print(time() - time_idx)
0.00012612342834472656
time_idx = time()
mainlist = list(set(mainlist) - (set(s1)|set(s2)))
print(time() - time_idx)
0.00010609626770019531
The improvement is significant since this is a small list.
Upvotes: 1
Reputation: 1383
Just use set operation to filter out
>>> list(set(mainlist) - set(s1+s2))
>>> [8, 9, 10, 11, 12, 13, 14, 15]
Upvotes: 0
Reputation: 40048
Probably you can create another list by using list comprehension
res = [i for i in test_list if i not in s1 and i not in s2]
or using filter() + lambda
res = filter(lambda i: i not in s1 and i not in s2, mainlist)
or using for
loop
for elem in mainlist:
if elem in s1 or elem in s2:
mainlist.remove(elem)
Upvotes: 2
Reputation: 54148
You can use list comprehension, it's ready good for that kind of problem :
result = [x for x in mainlist if x not in s1 and x not in s2]
Using list/set
manipulation you can do one of the following
result = list(set(mainlist) - (set(s1) | set(s2))) # remove the concat of s1&s2
result = list(set(mainlist) - set(s1) - set(s2)) # remove s1 and s2
Upvotes: 2