How do I compare 2 lists and order 1 based on the number of matches
<p>Say you had a list, for example:</p>

<pre><code>first_list = ['a', 'b', 'c']
</code></pre>

<p>And you had the following list:</p>

<pre><code>second_list = ['a', 'a b c', 'abc zyx', 'ab cc ac']
</code></pre>

<p>How would you create a function that simply re-orders the second list based on the total number of times an element from the entire first list matches any part of an individual string from the second list?</p>

<hr>

<p><strong>For further clarity:</strong></p>

<ul>
<li>in the second list the 'a' string would contain 1 match</li>
<li>the 'a b c' string would contain 3 matches</li>
<li>the second example list would essentially end up in reverse order once the function has finished</li>
</ul>

<hr>

<p><strong>My attempt:</strong></p>

<pre><code>first_list = ['a', 'b', 'c']
second_list = ['a', 'a b c', 'abc zyx', 'ab cc ac']

print second_list

i = 0
for keyword in first_list:
    matches = 0
    for s in second_list:
        matches += s.count(keyword)
        if matches &gt; second_list[0].count(keyword):
            popped = second_list.pop(i)
            second_list.insert(0, popped)

print second_list
</code></pre>

<p>Here's one unstable way to do it:</p>

<pre><code>&gt;&gt;&gt; l1 = ['a', 'b', 'c']
&gt;&gt;&gt; l2 = ['a', 'a b c', 'abc zyx', 'ab cc ac']
&gt;&gt;&gt; [s for _, s in sorted(((sum(s2.count(s1) for s1 in l1), s2) for s2 in l2), reverse=True)]
['ab cc ac', 'abc zyx', 'a b c', 'a']
</code></pre>

<p>If stable sort is required you could leverage <code>enumerate</code>:</p>

<pre><code>&gt;&gt;&gt; l1 = ['a', 'b', 'c']
&gt;&gt;&gt; l2 = ['a', 'a b c', 'ccc ccc', 'bb bb bb', 'aa aa aa']
&gt;&gt;&gt; [x[-1] for x in sorted(((sum(s2.count(s1) for s1 in l1), -i, s2) for i, s2 in enumerate(l2)), reverse=True)]
['ccc ccc', 'bb bb bb', 'aa aa aa', 'a b c', 'a']
</code></pre>

<p>Above generates tuples where second item is a string from <code>l2</code> and first item is the count of matches from <code>l1</code>:</p>

<pre><code>&gt;&gt;&gt; tuples = [(sum(s2.count(s1) for s1 in l1), s2) for s2 in l2]
&gt;&gt;&gt; tuples
[(1, 'a'), (3, 'a b c'), (3, 'abc zyx'), (6, 'ab cc ac')]
</code></pre>

<p>Then those tuples are sorted to descending order:</p>

<pre><code>&gt;&gt;&gt; tuples = sorted(tuples, reverse=True)
&gt;&gt;&gt; tuples
[(6, 'ab cc ac'), (3, 'abc zyx'), (3, 'a b c'), (1, 'a')]
</code></pre>

<p>And finally only the strings are taken:</p>

<pre><code>&gt;&gt;&gt; [s for _, s in tuples]
['ab cc ac', 'abc zyx', 'a b c', 'a']
</code></pre>

<p>In the second version tuples have reverse index to ensure stability:</p>

<pre><code>&gt;&gt;&gt; [(sum(s2.count(s1) for s1 in l1), -i, s2) for i, s2 in enumerate(l2)]
[(1, 0, 'a'), (3, -1, 'a b c'), (3, -2, 'abc zyx'), (6, -3, 'ab cc ac')]
</code></pre>

python