Question

I am new to Python. I have the following code which is a part of a string algorithm that i'm currently developing.

>>> newlist=[]
>>> i =0

>>> for x in range(len(list1)):
       new_item = [y for y in list1[i] if y not in list2[i]]
       newlist.append(new_item)
       i=i+1

>>> print newlist

I like to do this using list comprehension as I've read it is performance optimized. Can somebody suggest me a method.

Thank you.

[Edit]

example:

list1= [[['pat'],['cut'],['rat']],  [['sat','pat'],['cut','pat']],[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]

list2= [[['pat'], ['cut'], ['rat']], [['sat', 'pat']], [['instructor', 'plb', 'error0992'], ['instruction', 'address', '00x0993']]]

So the new list,

newlist= [[], [['cut', 'pat']], [['data', 'address', '017x112']]]
Was it helpful?

Solution

If you just want all elements that are in one list and not in another, I would suggest looking into python sets. They don't allow for duplicates, but the performance and readability benefits are large.

You would implement this like so:

newlist = list(set(list1).difference(set(list2)))

If you want to apply this in place of your current solutions, you should do something along the lines of what Dominic suggested (slightly edited for readability):

[list(set(a)-set(b)) for a, b in zip(list1, list2)]

If the order matters, or you have duplicates, then the single list comprehension you had above should do the trick, just wrap it as a lambda function to make it more readable:

single_item = lambda i: [y for y in list1[i] if y not in list2[i]]
newlist = [single_item(i) for i in enumerate(list1)]

OTHER TIPS

This is a nested list comprehension that does the same thing as your code (albeit will not preserve the value of i).

newlist = [[y for y in list1[i] if y not in list2[i]] for i in range(len(list1))]

TL;DR: [[y for y in list1[i] if j not in list2[i]] for i in enumerate(list1)]

You should use enumerate instead of the range(len()) non-idiom. You may also want to consider making this a generator expression. Either with a concrete nested list:

([y for y in list1[i] if j not in list2[i]] for i in enumerate(list1))

or not

((y for y in list1[i] if j not in list2[i]) for i in enumerate(list1))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top