Using a list comprehension to label data that is common to two lists
<p>I have two lists, A and B.  I want to generate a third list that is 1 if the corresponding entry in A has an entry in the list B at the end of the string and 0 otherwise.</p>

<pre><code>A = ['Mary Sue', 'John Doe', 'Alice Stella', 'James May', 'Susie May']
B = ['Smith', 'Stirling', 'Doe']
</code></pre>

<p>I want a list comprehension that will give the result</p>

<pre><code>[0, 1, 0, 0, 0]
</code></pre>

<p>Keep in mind that this is a specific case of a more general problem.  Elements in A can have arbitrary white space and contain an arbitrary number of words in them.  Likewise elements in B can have an arbitrary number of words.  For example</p>

<pre><code>A = ['  Tom Barry Stirling Adam', 'Maddox Smith', 'George Washington Howard Smith']
B = ['Washington Howard Smith', 'Stirling Adam']
</code></pre>

<p>should return</p>

<pre><code>[1, 0, 1]
</code></pre>

<p>So far I have the following</p>

<pre><code>[1 if y.endswith(x) else 0 for x in B for y in A]
</code></pre>

<p>However the length of the returned list is not the dimension that I want because it gives a 0 or 1 for every combination of A[i], B[j] elements.  I am not interested in solutions using for loops, I need a list comprehension for speed.</p>

<p>Your condition needs to hold the <code>B</code> list. Your proposed solution will generate a <code>0</code> or <code>1</code> for every pair of (A, B) elements.</p>

<pre><code>[1 if any(full.endswith(last) for last in B) else 0 for full in A]
</code></pre>

<p>But you can also take advantage of <code>bool</code> to <code>int</code> conversion</p>

<pre><code>[int(any(full.endswith(last) for last in B)) for full in A]
</code></pre>

<p>You can save some time by using a <code>set</code> and the <code>in</code> operator as well:</p>

<pre><code>B = {'Smith', 'Stirling', 'Doe'} # set for a more efficient `in`
[int(full.split()[-1] in B) for full in A]
</code></pre>

python python-3.x list-comprehension