运行itertools函数后对python字典进行排序

运行itertools函数后对python字典进行排序,python,sorting,dictionary,comparison,itertools,Python,Sorting,Dictionary,Comparison,Itertools,这个问题是由两个答案引导的两段代码的最终结果。我的第一个问题是如何比较两个字符串之间的相似性,我得到了一个很好的答案,如下代码所示: 代码1 def get_bigrams(string): ''' Takes a string and returns a list of bigrams ''' s = string.lower() return { s[i:i+2] for i in range(len(s) - 1) } def string_sim

这个问题是由两个答案引导的两段代码的最终结果。我的第一个问题是如何比较两个字符串之间的相似性,我得到了一个很好的答案,如下代码所示:

代码1

def get_bigrams(string):
    '''
    Takes a string and returns a list of bigrams
    '''
    s = string.lower()
    return { s[i:i+2] for i in range(len(s) - 1) }

def string_similarity(str1, str2):
    '''
    Perform bigram comparison between two strings
    and return a percentage match in decimal form
    '''
    pairs1 = get_bigrams(str1)
    pairs2 = get_bigrams(str2)
    intersection = set(pairs1) & set(pairs2)
    return (2.0 * len(intersection)) / (len(pairs1) + len(pairs2))
在那之后,我需要一种方法来对名称列表进行排序,以便通过上面的代码运行它们。我得到的代码如下所示:

代码2

import itertools
persons = ["Peter parker", "Richard Parker", "Parker Richard", "Aunt May"]
similarity = []
for p1, p2 in itertools.combinations(persons, 2):
    similarity.append(string_similarity(p1,p2))
    print("%s - %s: " %(p1, p2) + " " + str(string_similarity(p1, p2)))

similarity = sorted(similarity, key=float)
print(similarity)
现在,最后一个障碍是,我的数据不在列表中,实际上是从数据库中获取的,而数据库中的主键正是我最终想要跟踪的。也就是说,当我比较多个名称时,我需要标记ID 1和ID 2是最常见的变量。为了确定这两个ID是最不同的,我需要对上面“code1”的结果进行排序,如下所示:

Peter parker - Richard Parker:  0.5454545454545454
Peter parker - Parker Richard:  0.5454545454545454
Peter parker - Aunt May:  0.0
Richard Parker - Parker Richard:  0.8333333333333334
Richard Parker - Aunt May:  0.0
Parker Richard - Aunt May:  0.0
[0.0, 0.0, 0.0, 0.5454545454545454, 0.5454545454545454, 0.8333333333333334]

在我的头脑中,我需要的不是那些名字,而是用来获取名字的主要ID,所以我想使用字典。有没有办法使用
code2
运行{PID:Name}、{PID1:Name1}、PID2:Name2}字典,使用
code1
获取相似度值,对结果进行排序,然后知道相似度最高的名称是PID1和PID3?或者有没有一种比我现在想的更优雅、更不拉扯头发的方式……

是的,你需要把这对(身份证、姓名)联系起来。为此,您可以使用dict、元组甚至类。例如,使用元组,您的代码2将更改为:

persons = [('id1', "Peter parker"), ('id2' ,"Richard Parker"), ('id3' ,"Parker Richard"), ('id4' ,"Aunt May")]
similarity = [[p1, p2, string_similarity(p1[1], p2[1])]
                for p1, p2 in itertools.combinations(persons, 2)]

similarity = sorted(similarity, key=lambda x: x[2], reverse=True)
for p1, p2, sim in similarity:    
    print "{} - {}: {}".format(p1, p2, sim)  # p1[0], p2[0] to show ids only
你会得到:

('id2', 'Richard Parker') - ('id3', 'Parker Richard'): 0.833333333333
('id1', 'Peter parker') - ('id2', 'Richard Parker'): 0.545454545455
('id1', 'Peter parker') - ('id3', 'Parker Richard'): 0.545454545455
('id1', 'Peter parker') - ('id4', 'Aunt May'): 0.0
('id2', 'Richard Parker') - ('id4', 'Aunt May'): 0.0
('id3', 'Parker Richard') - ('id4', 'Aunt May'): 0.0

要在python中对字典进行“排序”,请看,我已经讨论了几个“如何对字典进行排序”线程,但在本例中是不同的。我需要一种方法将字典的值与键分开,将该值放入列表中,运行相似性代码,获得结果分数,按升序对分数排序,并找出该分数用于哪个ID。更好的是,有没有其他方法可以执行此任务,即使不使用字典,但仍然可以跟踪数据库主ID?使用前面链接中的代码,理解如何切分到列表中。假设
p={'PID':'Name','PID1':'Name1','PID2':'Name2'}
然后
print[p[PID]for PID in sorted(p,key=lambda x:x in p)]
将创建一个值列表,或者
['Name1',Name2',Name']
。总有另一种方法。我的意思是
[p[pid]对于排序中的pid(p,key=lambda x:x)]
将创建
['Name'、'Name1'、'Name2']
。你做到了。谢谢你抽出时间。以我目前的python技能水平,我永远不会解决它。