Reputation: 3885
I have 3 lists:
l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
l2 = ['a', 'g', 'h', 'd', 'k']
l3 = ['z', 'b', 'v', 'n', 'k', 's']
I want to create some kind of filter, that will leave only unique elements in these 3 lists. So l1
should have only elements that are not in l2
and l3
, and I want to do the same for every list.
Desired output:
l1 = ['c', 'e', 'q', 'w']
l2 = ['g', 'h']
l3 = ['z', 'v', 'n', 's']
I have 6 lists with more than 5000 elements each, and lists are not the same length. I was thinking of doing some kind of intersections, but I'll have to make a lot of for loops.
Is there any Pythonic way for this?
Upvotes: 0
Views: 71
Reputation: 71454
I'd use a Counter
:
>>> l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
>>> l2 = ['a', 'g', 'h', 'd', 'k']
>>> l3 = ['z', 'b', 'v', 'n', 'k', 's']
>>> import collections
>>> counter = collections.Counter(l1 + l2 + l3)
>>> [i for i in l1 if counter[i] == 1]
['c', 'e', 'q', 'w']
>>> [i for i in l2 if counter[i] == 1]
['g', 'h']
>>> [i for i in l3 if counter[i] == 1]
['z', 'v', 'n', 's']
Note that if you have a bunch of lists you want to do exactly the same thing to, you probably just want to have a list of lists rather than a bunch of individual variables:
>>> all_lists = [l1, l2, l3]
>>> counter = collections.Counter(i for a in all_lists for i in a)
>>> [[i for i in a if counter[i] == 1] for a in all_lists]
[['c', 'e', 'q', 'w'], ['g', 'h'], ['z', 'v', 'n', 's']]
Upvotes: 7
Reputation: 4975
Here the set
approach. It is combinatorics based so it depends on the amount of lists, n, only. The loop will always iterate n-times since "n choose n-1" = n.
Drawback: final lists will be (randomly) sorted
Advantage: "construction" exact solution
import itertools as it
l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
l2 = ['a', 'g', 'h', 'd', 'k']
l3 = ['z', 'b', 'v', 'n', 'k', 's']
ls = (l1, l2, l3)
# as dictionary with key integer numbers and values sets
d = {i: set(ls[i]) for i in range(len(ls))}
results = []
s = set(d.keys())
for p in it.combinations(d.keys(), len(ls)-1):
# index not comparing in p
i = tuple(s.difference(p))[0]
# new set
s_new = d[i].difference(set.union(*map(d.__getitem__, p)))
results.append(list(s_new))
print(results)
Output
[['v', 's', 'n', 'z'], ['h', 'g'], ['e', 'c', 'w', 'q']]
Upvotes: 0