-2

I am looking to get the difference between two lists.

I am looking for a solution like this only I want to consider non-unique list values.

x = [1, 1, 2, 2, 3]
y = [1, 2]

# i want
z = x - y
# z = [1, 2, 3]

The solution above my code turns the two lists into sets which allows the - operator to work on them but removes non unique values from the lists. Can you think of a simple 'one liner' solution that does what im looking for?

Community
  • 1
  • 1
ThriceGood
  • 1,633
  • 3
  • 25
  • 43
  • More information is required. What is the desired output for x = [1, 1, 1, 2], y=[1]? What is the desired output for x = [1], y=[2]? – Kevin Oct 28 '15 at 17:13
  • see above, im looking to just return the difference, or the leftovers from x - y, im not too worried about x or y afterwards – ThriceGood Oct 28 '15 at 17:22
  • _"im not too worried about x or y afterwards."_ I don't understand. I didn't say anything about preserving the original contents of the lists. Please just answer my questions. – Kevin Oct 28 '15 at 17:25
  • Do you want to preserve the order of the values in list `x` in the result? – martineau Oct 28 '15 at 17:27
  • `x=[1,1,1,2], y=[1]` = `[1,1,2]`, just removes the one `1`, for `x=[1], y=[2]` = `[1]`, `2` is not removed as its not in the `x` list. that wont be a case in the code as `y` will always have elements of `x`. preservation of order is not important – ThriceGood Oct 28 '15 at 17:29

4 Answers4

1

You could use collections.Counter to find the counts of elements in each list. Then you can take the difference and reconstruct a list from the results.

>>> from collections import Counter
>>> x = [1, 1, 2, 2, 3]
>>> y = [1, 2]
>>> [k for _ in range(v) for k,v in (Counter(x) - Counter(y)).iteritems()]
[1, 2, 3]

The drawback being, the order of the result has no real correlation with the order of the input lists. The fact that the result shown above looks sorted is implementation-dependent and possibly only a coincidence.

Kevin
  • 74,910
  • 12
  • 133
  • 166
1

might not be fancy, first thing that came to mind..

x=[1,1,2,2,3]
y=[1,2]

_ = [ x.remove(n) for n in y if n in x ]

x
[1,2,3]
  • Using a list comprehension simply for its side-effects (in order to create a "one-liner") is considered wasteful and basically a poor practice by many. – martineau Oct 28 '15 at 17:13
  • @martineu, could you explain your comment? for curiosity and learning, what is a 'list comprehension'? – ThriceGood Oct 28 '15 at 20:24
1

Here's my take:

x = [1, 1, 2, 2, 3]
y = [1, 2]
z = [n for n in y if (n in x) and x.remove(n)] + x
print(z)  # -> [1, 2, 3]

x = [1, 1, 1, 2]
y = [1]
z = [n for n in y if (n in x) and x.remove(n)] + x
print(z)  # -> [1, 1, 2]
martineau
  • 119,623
  • 25
  • 170
  • 301
0

You just described the union of two sets, so use set:

>>> list(set(x).union(set(y)))
[1, 2, 3]
mtzl
  • 404
  • 2
  • 13