基于具有最高相似度的值对字典列表进行排序

时间:2013-10-01 14:33:26

标签: python sorting go

给出以下字典的python列表:

results = [[{'id': '001', 'result': [0,0,0,0,1]},
           {'id': '002', 'result': [1,1,1,1,1]},
           {'id': '003', 'result': [0,1,1,None,None]},
           {'id': '004', 'result': [0,None,None,1,0]},
           {'id': '005', 'result': [1,0,None,1,1]},
           {'id': '006', 'result': [0,0,0,1,1]}],
          [{'id': '001', 'result': [1,0,1,0,1]},
           {'id': '002', 'result': [1,1,1,1,1]},
           {'id': '003', 'result': [0,1,1,None,None]},
           {'id': '004', 'result': [0,None,None,1,0]},
           {'id': '005', 'result': [1,0,None,1,1]},
           {'id': '006', 'result': [1,0,1,0,1]}]
            ]

我想基于'结果'的值生成一个新的排序列表(在python和golang中),通过比较每个组中的玩家('id')之间的结果,然后根据它们的数量对它们进行排序。匹配条目(没有结果被丢弃而不计算):

在第一轮和第二轮中,001和006有九个匹配的答案:
001 = [0,0,0,0,1] 006 = [0,0,0,1,1] - 四个匹配的答案 在第二轮中,001和006有五个匹配的答案:
001 = [1,0,1,0,1] 006 = [1,0,1,0,1] - 五个匹配答案

sorted_results = ['001','006','002','005','003','004']

'001'和'006'是列表中的前两项,因为它们具有最高匹配结果数 - 九。

2 个答案:

答案 0 :(得分:1)

如果您按“最大数量的相同结果”对这些项目进行排序,则可以获得以下结果:

['003', '004', '005', '006', '001', '002']

如果您有其他意义(即不是“相同结果的最高数量”),请澄清您的问题。此外,您只需修改max_identical函数,使其根据您的类似定义行事。

上述结果计算如下:

from collections import defaultdict


results = [{'id': '001', 'result': [0, 0, 0, 0, 1]},
           {'id': '002', 'result': [1, 1, 1, 1, 1]},
           {'id': '003', 'result': [0, 1, 1, None, None]},
           {'id': '004', 'result': [0, None, None, 1, 0]},
           {'id': '005', 'result': [1, 0, None, 1, 1]},
           {'id': '006', 'result': [0, 0, 0, 1, 1]}]


def max_identical(lst):
    counts = defaultdict(lambda: 0)
    for x in lst:
        if x is not None:
            counts[x] += 1
    return max(counts.values())


results = sorted(results, key=lambda x: max_identical(x['result']))

print [x['id'] for x in results]

答案 1 :(得分:0)

寻找与您非常相似的问题的解决方案我找到了这个页面: http://w3facility.org/question/sorting-a-python-dictionary-after-running-an-itertools-function/

使用您的示例:

import itertools
results = [[{'id': '001', 'result': [0,0,0,0,1]},
           {'id': '002', 'result': [1,1,1,1,1]},
           {'id': '003', 'result': [0,1,1,None,None]},
           {'id': '004', 'result': [0,None,None,1,0]},
           {'id': '005', 'result': [1,0,None,1,1]},
           {'id': '006', 'result': [0,0,0,1,1]}],
          [{'id': '001', 'result': [1,0,1,0,1]},
           {'id': '002', 'result': [1,1,1,1,1]},
           {'id': '003', 'result': [0,1,1,None,None]},
           {'id': '004', 'result': [0,None,None,1,0]},
           {'id': '005', 'result': [1,0,None,1,1]},
           {'id': '006', 'result': [1,0,1,0,1]}]
          ]

这将创建id的全部与全部比较,每个比较用于每轮。

similarity = {}
for p1, p2 in itertools.combinations(results[0], 2):
    similarity.setdefault((p1["id"], p2["id"]), sum([1 for i in range(len(p1["result"])) if p1["result"][i] == p2["result"][i]]))
for p1, p2 in itertools.combinations(results[1], 2):
    similarity.setdefault((p1["id"], p2["id"]), 0)
    similarity[(p1["id"], p2["id"])] += sum([1 for i in range(len(p1["result"])) if p1["result"][i] == p2["result"][i]])

现在按照匹配值对id对进行排序,将返回有序的id元组列表。

similarity = sorted(similarity, key=lambda x:similarity[x], reverse=True)
print(similarity)

现在要消除重复的值,只需按顺序保留每个id的第一次出现,而忘记其余的。

sorted_ids = []
for tuple_id in similarity:
    if tuple_id[0] not in sorted_ids:
        sorted_ids.append(tuple_id[0])
    if tuple_id[1] not in sorted_ids:
        sorted_ids.append(tuple_id[1])

print sorted_ids