Calculating similarity "score" between multiple dictionaries
<p>I have a reference dictionary, "dictA" and I need to compare it (calculate similarity between key and vules) to n amount of dictionaries that are generated on the spot. Each dictionary has the same length. Lets say for the sake of the discussion that the n amount of dictionaries to compare it with is 3: dictB, dictC, dictD.</p>

<p>Here is how dictA looks like:</p>

<pre><code>dictA={'1':"U", '2':"D", '3':"D", '4':"U", '5':"U",'6':"U"}
</code></pre>

<p>Here are how dictB,dictC and dictD look like:</p>

<pre><code>dictB={'1':"U", '2':"U", '3':"D", '4':"D", '5':"U",'6':"D"}
dictC={'1':"U", '2':"U", '3':"U", '4':"D", '5':"U",'6':"D"}
dictD={'1':"D", '2':"U", '3':"U", '4':"U", '5':"D",'6':"D"}
</code></pre>

<p>I have a solution, but just for the option of two dictionaries:</p>

<pre><code>sharedValue = set(dictA.items()) &amp; set(dictD.items())
dictLength = len(dictA)
scoreOfSimilarity = len(sharedValue)
similarity = scoreOfSimilarity/dictLength
</code></pre>

<p>My questions is:
How can I iterate through n amount of dictionaries with dictA being a primary dictionary which I compare others with. The goal is to get a "similarity" value for each dictionary I am gonna iterate through against the primary dictionary. </p>

<p>Thanks for your help.</p>

<p>If you stick your solution in a function, you can call it by name for any two dicts. Also, if you curry the function by breaking up the arguments across nested functions, you can partially apply the first dict to get back a function that just wants the second (or you could use <code>functools.partial</code>), which makes it easy to map:</p>

<pre><code>def similarity (a):
    def _ (b):
        sharedValue = set(a.items()) &amp; set(b.items())
        dictLength = len(a)
        scoreOfSimilarity = len(sharedValue)
        return scoreOfSimilarity/dictLength
    return _
</code></pre>

<p>Aside: the above can also be written as a single expression via nested lambdas:</p>

<pre><code>similarity = lambda a: lambda b: len(set(a.items()) &amp; set(b.items)) / len(a)
</code></pre>

<p>Now you can get the similarity between dictA and the remainder with a map:</p>

<pre><code>otherDicts = [dictB, dictC, dictD]
scores = map(similarity(dictA), otherdicts)
</code></pre>

<p>Now you can use <code>min()</code> (or <code>max()</code>, or whatever) to get the best from the scores list:</p>

<pre><code>winner = min(scores)
</code></pre>

<p>Warning: I have not tested any of the above.</p>

python python-3.x