在字典列表中根据值查找相似项

5
我希望能够从一个Django数据库中匹配相似的文章,根据标签,这些标签存储在类似以下格式的字典列表中:
myarticle = {'pk': 17, 'tags': [0, 1, 0, 1, 0]}
allarticles = [{'pk': 1, 'tags': [0, 0, 0, 1, 0]}, 
               {'pk': 2, 'tags': [0, 1, 0, 1, 0]},
               {'pk': 3, 'tags': [1, 1, 0, 0, 0]},
               {'pk': 4, 'tags': [1, 0, 1, 0, 1]},
               {'pk': 5, 'tags': [0, 0, 0, 0, 1]}]

什么是获取基于输入的文章匹配标签数排序列表的最便捷方法?预期结果:
result = [2, 1, 3, 5, 4]

3
看起来您想让我们为您编写一些代码。虽然很多用户都愿意在程序员遇到问题时提供帮助,但通常只会在发帖者已经尝试过解决问题的情况下提供帮助。展示这种努力的好方法是包括您已经编写的代码、示例输入(如果有的话)、预期输出和实际输出(控制台输出、跟踪等)。提供的细节越多,您可能得到的答案就会越多。请查看[FAQ]和[ask]。 - MooingRawr
2个回答

6
你可以使用sorted函数:
myarticle = {'pk': 17, 'tags': [0, 1, 0, 1, 0]}
allarticles = [{'pk': 1, 'tags': [0, 0, 0, 1, 0]}, 
           {'pk': 2, 'tags': [0, 1, 0, 1, 0]},
           {'pk': 3, 'tags': [1, 1, 0, 0, 0]},
           {'pk': 4, 'tags': [1, 0, 1, 0, 1]},
           {'pk': 5, 'tags': [0, 0, 0, 0, 1]}]
new_articles = sorted(allarticles, key=lambda x:sum(a == b for a, b in zip(myarticle['tags'], x['tags'])), reverse=True)
final_results = [i['pk'] for i in new_articles]

输出:

[2, 1, 3, 5, 4]

2

您可以使用第三方 NumPy 实现矢量化解决方案,通过 numpy.argsort

对于更大的输入列表,这应该更加高效:

allarticles = allarticles*10000

import numpy as np

def jp(myarticle, allarticles):
    arr = np.argsort((np.array([d['tags'] for d in allarticles]) == myarticle['tags']).sum(1))[::-1]
    return [allarticles[i]['pk'] for i in arr]

def ajax(myarticle, allarticles):
    new_articles = sorted(allarticles, key=lambda x:sum(a == b for a, b in zip(myarticle['tags'], x['tags'])), reverse=True)
    return [i['pk'] for i in new_articles]

%timeit jp(myarticle, allarticles)    # 49.3 ms per loop
%timeit ajax(myarticle, allarticles)  # 112 ms per loop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接