Find difference in list with identical values
<p>I need to be able to find differences in list that may have identical values to one another besides two added elements</p>

<p>example</p>

<pre><code>a = ['cool task', 'b', 'another task', 'j', 'better task', 'y']
b = ['cool task', 'b', 'a task', 'j', 'another task', 'j', 'better task', 'y']
</code></pre>

<p>How my problem is, both <code>'a task'</code> and <code>'another task'</code> both are followed by a <code>'j'</code></p>

<pre><code>[x for x in b if x not in a]
['a task']
</code></pre>

<p>Because both <code>a</code> and <code>b</code> contain <code>'j'</code>, it is removed from the list.</p>

<p>How would I make so that I end up with </p>

<pre><code>['a task', 'j']
</code></pre>

<p>You could use the <a href="https://docs.python.org/3/library/difflib.html#sequencematcher-objects" rel="nofollow"><code>difflib.SequenceMatcher()</code> class</a> to enumerate added, removed and changed entries:</p>

<pre><code>&gt;&gt;&gt; from difflib import SequenceMatcher
&gt;&gt;&gt; matcher = SequenceMatcher(a=a, b=b)
&gt;&gt;&gt; added = []
&gt;&gt;&gt; for tag, i1, i2, j1, j2 in matcher.get_opcodes():
...     if tag == 'insert':
...         added += b[j1:j2]
...
&gt;&gt;&gt; added
['a task', 'j']
</code></pre>

<p>The above only focuses on added entries; if you need to know about entries that were <em>removed</em> or altered, then there are opcodes for those events too, see the <a href="https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.get_opcodes" rel="nofollow"><code>SequenceMatcher.get_opcodes()</code> method documentation</a>.</p>

<p>However, if your entries are always <em>paired</em>, then just produce sets with tuples from them (using <a href="http://stackoverflow.com/questions/5389507/iterating-over-every-two-elements-in-a-list">pair-wise iteration</a>); you can then do any set operations on these:</p>

<pre><code>aset = set(zip(*([iter(a)] * 2)))
bset = set(zip(*([iter(b)] * 2)))
difference = bset - aset
</code></pre>

<p>Demo:</p>

<pre><code>&gt;&gt;&gt; aset = set(zip(*([iter(a)] * 2)))
&gt;&gt;&gt; bset = set(zip(*([iter(b)] * 2)))
&gt;&gt;&gt; aset
{('another task', 'j'), ('cool task', 'b'), ('better task', 'y')}
&gt;&gt;&gt; bset
{('a task', 'j'), ('another task', 'j'), ('cool task', 'b'), ('better task', 'y')}
&gt;&gt;&gt; bset - aset
{('a task', 'j')}
</code></pre>

python