Python中字符串和整数元组的字典列表

0 投票
2 回答
811 浏览
提问于 2025-04-18 00:37

我正在尝试返回一个包含 (str, int) 元组的列表,这个列表是给定人推荐的朋友。这个列表是从一系列元组中提取的,每个元组的第一个元素是潜在朋友的名字(格式和字典的键一样),第二个元素是这个潜在朋友的得分。只有得分不为零的潜在朋友才会被包含在列表中。

下面是这个函数返回值格式的一个例子:

[('Gloria Pritchett', 2),
 ('Manny Delgado', 1),
 ('Cameron Tucker', 1),
 ('Luke Dunphy', 3)]

对于每个人,社交网络中所有他们目前不是朋友的人都是潜在朋友。对于某个特定的人,每个潜在朋友的得分是通过以下方式计算的:

  • 如果这个人和潜在朋友有共同的朋友,就给潜在朋友的得分加1分。
  • 如果这个人和潜在朋友属于同一个网络,也给潜在朋友的得分加1分。
  • 如果这个人和潜在朋友有相同的姓氏,得分也加1分,但前提是他们之间还有其他共同点(共同的朋友、共同的网络或两者都有)。

这是我做的:

我有两个函数,它们运行得很好:

  • 第一个函数返回一个字典,键是名字,值是朋友的名字。
  • 第二个函数返回一个字典,键是名字,值是网络。

但是在 def make_recommendations 这个地方我遇到了错误。我不知道问题出在哪里……请帮帮我。

2 个回答

0

我看到这个问题有点复杂,而且涉及很多交集,我建议你简化一下解决方案,把它分成几个步骤:

比如说:

  1. 写一个函数来找出一个人朋友的分数(返回一个元组列表):

    def friendsMu(person):
        result = []
        friends = person_to_friends[person]
        for key in person_to_friends:
            if key != person:
                friends2 = person_to_friends[key]
                intersect = list(set(friends) & set(friends2))
                p = len(intersect)
                if p != 0:
                    t = (key, p)
                    result.append(t)
        return result
    
  2. 写一个函数来找出一个人社交网络的分数(返回一个元组列表):

    def networkMu(person):
        result = []
        friends = person_to_networks[person]
        for key in person_to_networks:
            if key != person:
                friends2 = person_to_networks[key]
                intersect = list(set(friends) & set(friends2))
                p = len(intersect)
                if p != 0:
                    t = (key, p)
                    result.append(t)
        return result
    
  3. 写一个函数来计算前面函数的结果,针对所有人(返回一个字典: = 名字 = 元组列表):

    def allf();
        ddict = {}
        for key in person_to_friends:
            d1 = friendsMu(key)
            if d1 != ():
                ddict[key] = d1
        return ddict
    
    def alln():
        ndict = {}
        for key in person_to_networks:
            d1 = networkMu(key)
            if d1 != ():
                ndict[key] = d1
        return ndict
    
  4. 写一个函数来合并最终结果:

    from collections import Counter
    def mrg(ddict, ndict):
        merged = Counter(ddict)
        merged.update(ndict)
        return merged
    

输出结果可能看起来像这样:

 print allf()
 allf() =  {'Jay Pritchett': [('Manny Delgado', 1), ('Cameron Tucker', 1), ('Gloria Pritchett', 1), ('Luke Dunphy', 1)], 'Claire Dunphy': [('Gloria Pritchett', 1), ('Luke Dunphy', 1)], 'Manny Delgado': [('Jay Pritchett', 1), ('Mitchell Pritchett', 1), ('Alex Dunphy', 1), ('Cameron Tucker', 1)], 'Mitchell Pritchett': [('Manny Delgado', 1), ('Phil Dunphy', 1), ('Alex Dunphy', 1)], 'Alex Dunphy': [('Manny Delgado', 1), ('Mitchell Pritchett', 1)], 'Cameron Tucker': [('Jay Pritchett', 1), ('Manny Delgado', 1), ('Luke Dunphy', 1)], 'Haley Gwendolyn Dunphy': [], 'Phil Dunphy': [('Mitchell Pritchett', 1)], 'Dylan D-Money': [], 'Gloria Pritchett': [('Jay Pritchett', 1), ('Claire Dunphy', 1), ('Luke Dunphy', 1)], 'Luke Dunphy': [('Jay Pritchett', 1), ('Claire Dunphy', 1), ('Cameron Tucker', 1), ('Gloria Pritchett', 1)]}

 print alln()
 alln() =  {'Phil Dunphy': [], 'Claire Dunphy': [('Gloria Pritchett', 1)], 'Manny Delgado': [('Alex Dunphy', 1)], 'Mitchell Pritchett': [], 'Alex Dunphy': [('Manny Delgado', 1)], 'Cameron Tucker': [], 'Gloria Pritchett': [('Claire Dunphy', 1)]}

merged = mrg(allf(),alln())
for i in merged:                                                                 
    print i, merged[i]
merged = 
Jay Pritchett [('Manny Delgado', 1), ('Cameron Tucker', 1), ('Gloria Pritchett', 1), ('Luke Dunphy', 1)]
Claire Dunphy [('Gloria Pritchett', 1), ('Luke Dunphy', 1), ('Gloria Pritchett', 1)]
Manny Delgado [('Jay Pritchett', 1), ('Mitchell Pritchett', 1), ('Alex Dunphy', 1), ('Cameron Tucker', 1), ('Alex Dunphy', 1)]
Mitchell Pritchett [('Manny Delgado', 1), ('Phil Dunphy', 1), ('Alex Dunphy', 1)]
Alex Dunphy [('Manny Delgado', 1), ('Mitchell Pritchett', 1), ('Manny Delgado', 1)]
Cameron Tucker [('Jay Pritchett', 1), ('Manny Delgado', 1), ('Luke Dunphy', 1)]
Haley Gwendolyn Dunphy []
Phil Dunphy [('Mitchell Pritchett', 1)]
Dylan D-Money []
Gloria Pritchett [('Jay Pritchett', 1), ('Claire Dunphy', 1), ('Luke Dunphy', 1), ('Claire Dunphy', 1)]
Luke Dunphy [('Jay Pritchett', 1), ('Claire Dunphy', 1), ('Cameron Tucker', 1), ('Gloria Pritchett', 1)]

希望这能帮到你,虽然可能不能完全满足你的要求,但可以给你一些指导。祝你好运。

1

我不太确定这段代码是不是在做你想的事情:

for key in person_to_friends or person_to_networks:

你可以通过尝试这个来看看它到底在做什么:

for x in [1,2,3] or [4,5,6]:
    print x

这实际上是在说:

for value in (first list if it's not empty otherwise second list)

如果你想同时使用两个列表里的值,应该用 itertools.chain

import itertools
for x in itertools.chain([1,2,3], [4,5,6]):
    print x

你在这里也犯了类似的错误:

if freind in person_to_friends[profiles_file] or person_to_networks[profiles_file]:

(注意 freind 的拼写错误。这可能是导致你出错的原因。另外 profiles_file 在这个函数里没有定义,是不是在全局范围内?) 你可能是想:

if friend in person_to_friends[profiles_file] or friend in person_to_networks[profiles_file]:

这段代码被 Python 解释为:

if (value in first sequence) OR (second sequence is not empty)

另外要注意的是,在 person_to_friends 里,你有:

name.update({lst[0]:lst[1:]})

虽然这在技术上是正确的,但比起传统的方法,这样做会增加很多复杂性(无论是理解上还是处理上):

name[lst[0]] = lst[1:]

撰写回答