Reputation: 2123
I'm learning python and would like to understand what is happening here. I'm sure I'm missing something basic. I'm getting elements from two lists that do not show up in both. Here is my code with output:
l = [1, 8, 3, 4]
m = [4, 6, 3, 8]
Method 1:
r = list(set(l) - set(m)) + list(set(m) - set(l))
[1, 6]
Method 2:
print [(x,y) for x in l for y in m if x not in m and y not in l]
[(1, 6)]
Method 3 (same but returns a list):
print [[x,y] for x in l for y in m if x not in m and y not in l]
[[1, 6]]
I would like a list comprehension that would return the same list as returned by method 1.
Also, as far as I understand I'm getting a generator as a result of the code in list comprehension. However, I cannot turn it into a simple list:
res = ((x,y) for x in l for y in m if x not in m and y not in l)
print list(res)
[(1, 6)]
Why is that? I'm expecting:
[1, 6]
EDIT: my main question is: why can't I turn generator from my list comprehension above into a list? According to the accepted answer in this question using list(res)
should work. I want to understand why it doesn't.
Upvotes: 2
Views: 502
Reputation: 403128
list(set(l) - set(m)) + list(set(m) - set(l))
is a windy way of finding the symmetric difference between two sets ("the set of elements which are in either of the sets and not in their intersection"—Wikipedia).
>>> set(l).symmetric_difference(m)
{1, 6}
Anyway, with a list comprehension, this is how I'd do it:
>>> {el for (this,other) in [(m,l),(l,m)] for el in this if el not in other}
{1, 6}
Which is the same as
>>> symdif = set()
>>> for this,other in [(m,l),(l,m)]:
... for el in this:
... if el not in other:
... symdif.add(el)
...
>>> symdif
{1, 6}
...not that I'd recommend it.
Upvotes: 2
Reputation: 71610
It's because your converting the generator to a list!
So it's gonna be equivalent to a list comprehension!!!
Also another option is:
list(set(l)^set(m))
Very short and good.
Upvotes: 1