views:

215

answers:

6

Take two lists, second with same items than first plus some more:

a = [1,2,3]
b = [1,2,3,4,5]

I want to get a third one, containing only the new items (the ones not repeated):

c = [4,5]

The solution I have right now is:

>>> c = []
>>> for i in ab:
...   if ab.count(i) == 1:
...     c.append(i)
>>> c
[4, 5]

Is there any other way more pythonic than this?

Thanx folks!

+11  A: 

at the very least use a list comprehension:

[x for x in a + b if (a + b).count(x) == 1]

otherwise use the set class:

list(set(a).symmetric_difference(set(b)))

there is also a more compact form:

list(set(a) ^ set(b))
UncleZeiv
If the code will be read by someone else, who may or may not be too familiar with python, the second option is better than the third in that it is more readable. Unless everyone who reads your code has memorized the 'set' operators, that is...
tgray
+7  A: 

If the order is not important and you can ignore repetitions within a and b, I would simply use sets:

>>> set(b) - set(a)
set([4, 5])

Sets are iterable, so most of the times you do not need to explicitly convert them back to list. If you have to, this does it:

>>> list(set(b) - set(a))
[4, 5]
krawyoti
The only problem with this solution is that it will ignore items that only occur in set(a), you probably want the symmetric_difference.
tgray
The symmetric difference finds you the elements in a that are not in b or those in b that are not in a.Unless I'm mistaken, nabucosound asks for the elements that have been added in b that were not in a. So, simple set difference seems sufficient.
krawyoti
+4  A: 

Items in b that aren't in a, if you need to preserve order or duplicates in b:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 4, 5]
>>> a_set = set(a)
>>> [x for x in b if x not in a_set]
[4, 4, 5]

Items in b that aren't in a, not preserving order, and not preserving duplicates in b:

>>> list(set(b) - set(a))
[4, 5]
Roger Pate
+3  A: 

I'd say go for the set variant, where

  set(b) ^ set(a)   (set.symmetric_difference())

only applies if you can be certain that a is always a subset of b, but in that case has the advantage of being commutative, ie. you don't have to worry about calculating set(b) ^ set(a) or set(a) ^ set(b); or

  set(b) - set(a)    (set.difference())

which matches your description more closely, allows a to have extra elements not in b which will not be in the result set, but you have to mind the order (set(a) - set(b) will give you a different result).

ThomasH
A: 

Another solution using only lists:

a = [1, 2, 3]
b = [1, 2, 3, 4, 5]
c = [n for n in a + b if n not in a or n not in b]
mtasic
+1  A: 

Here are some different possibilities with the sets

>>> a = [1, 2, 3, 4, 5, 1, 2]
>>> b = [1, 2, 5, 6]
>>> print list(set(a)^set(b))
[3, 4, 6]
>>> print list(set(a)-set(b))
[3, 4]
>>> print list(set(b)-set(a))
[6]
>>> print list(set(a)-set(b))+list(set(b)-set(a))
[3, 4, 6]
>>>
luc