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>How big is B in real life? You could turn it into a regular expression.</p>

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

<p>turn B into <code>".*(?:Smith|Stirling|Doe)$"</code> then compile to regex    </p>

<pre><code>import re
end_with_b = re.compile(".*(?:{})$".format("|".join(B))

a_matches = [1 if ends_with_b.match(a) else 0 for a in A]
</code></pre>

<p>Or, create your own filter function</p>

<pre><code>def my_filter(a):
    return 1 if any(a.endswith(b) for b in B) else 0

a_matches = [my_filter(a) for a in A]
</code></pre>

python python-3.x list-comprehension