Reputation: 701
Here's the task I am having trouble with:
Given 2 lists of lists, filter them down to only items that have nothing in common. E. g. if inner lists are identical, filter them out. If inner lists have at least one item in common, also filter them out.
Note: There is only one level of nesting. The inner lists consist only of strings. I have a solution that works, but it's EXTREMELY messy. Looking for feedback to improve:
First I filter out the exact matches in both lists:
l3 = filter(lambda x: x not in l2, l1)
l4 = filter(lambda x: x not in l1, l2)
I end up with 2 lists of lists that do not have exactly the same items. Now I want to iterate over the inner lists, and get rid of any of them that share items with any of the inner lists of the other.
I am doing:
for i in l3:
for j in i:
for k in l4:
if j in k:
print j, k
removel3.append(tuple(i))
removel4.append(tuple(k))
for i in l4:
for j in i:
for k in l3:
if j in k:
removel3.append(tuple(k))
removel4.append(tuple(i))
for i in list(set(removel3)):
l3.remove(list(i))
for i in list(set(removel4)):
l4.remove(list(i))
(building separate lists of things to remove from lists because removing directly in the iterating loop messes up list indexing and skips items. There has to be a better way of doing it, but I don't know of it.)
But yeah. It gets the job done, but going from tuples to sets to lists to more tuples... sounds very nonpythonic. :) Would be happy to see any feedback!
EDIT:
Sample input:
l1 = [['A', 'B', 'C'], ['D', 'E'], ['F', 'G', 'H']]
l2 = [['A', 'B', 'C'], ['D', 'I'], ['K', 'L', 'M']]
After all the transformations above, end up with:
>>> l3
[['F', 'G', 'H']]
>>> l4
[['K', 'L', 'M']]
Upvotes: 2
Views: 169
Reputation: 113950
I think a filter like this is what you want
filter(lambda sublist:not any(set(sublist).intersection(x) for x in list2),list1)
Upvotes: 2
Reputation: 309861
I'm not sure that I understand you, but I'm gonna give it a shot.
# first, get all elements from each list as a flat set.
import itertools
set1 = set(itertools.chain.from_iterable(list1))
set2 = set(itertools.chain.from_iterable(list2))
#Now, figure out which elements they have in common
common_elements = set1 & set2
#Now eliminate inner lists which have elements in the common set
new_list1 = [lst for lst in list1 if not any(x in common_elements for x in lst)]
new_list2 = [lst for lst in list2 if not any(x in common_elements for x in lst)]
Note that I can do this because the sublists hold hashable objects.
Upvotes: 4