Python3朋友的朋友

问题描述

我正在使用此功能来查找两个人之间可能的友谊。友谊系统以传递方式工作,即,如果A是B的朋友,并且B是C的朋友,则A是C的朋友。字典存储初始关系(如图形)和函数参数是词典,以及您想识别两个人是否是朋友的名字。

def findfriendship(people,X,Y):
    if Y in people[X] or X in people[Y]:
        return True

    if len(people[X]) != 0:
        for friend in people[X]:
            return findfriendship(people,friend,Y)

    if len(people[Y]) != 0:
        for friend in people[Y]:
            return findfriendship(people,friend)

    return False

这是我的代码,只要两个人中有一个不为空的朋友列表,我就成功地确定了两个人之间可能的友谊,

friendships = {'Jordan': ['Shaq'],'Lebron': [],'Kobe': [],'Shaq': ['KD'],'KD': []}
print(findfriendship(friendships,'KD','Jordan')) -> return True

但是我不能解决两个都没有直接朋友的问题,

friendships = {'Jordan': ['Shaq'],'Kobe': ['KD','Lebron'],'Lebron','KD')) -> return False

它返回False,但是Kobe是他们两个的朋友,所以他们应该是朋友。

你们能帮助我尝试解决这个问题吗?或者您知道类似的问题,以便我能够理解这种类型的概念吗?感谢您的关注。

解决方法

如果我们可以获取每个人的完整朋友列表,则检查两个人是否为朋友将很容易。让我们为此写一个助手:

friendships = {
    'Jordan': ['Shaq'],'Lebron': [],'Kobe': ['KD','Lebron'],'Shaq': ['KD'],'KD': [],"foo": ["bar","baz"],"bar": [],"baz":[],}

def buildFriendSet (x,people=None,fSet=None):
    people = people or friendships;       # default value
    fSet = fSet or set([x] + people[x]);  # Friend Set
    changeDetected = False;
    for kPerson,vPersonList in people.items():
        personList = [kPerson] + vPersonList;
        if fSet.issuperset(personList):
            pass;
        elif fSet.intersection(personList):
            fSet = fSet.union(personList);
            changeDetected = True;
    if not changeDetected:
        return fSet;
    return buildFriendSet(x,people,fSet);

print(buildFriendSet('KD'));
# Output: {'Shaq','Kobe','KD','Lebron','Jordan'}

print(buildFriendSet('foo'))
# Output: {'baz','bar','foo'}

一旦我们可以为任何人计算出一组朋友,就很容易检查两个人是否是朋友:

def checkFriends (x,y,people=None):
    people = people or friendships; # default value
    return (x in people[y] or y in people[x] or
        x in buildFriendSet(y,people)
    );

print(checkFriends('KD','Jordan')); # -> True
print(checkFriends('Lebron','KD')); # -> True
print(checkFriends('KD','foo'));    # -> False

buildFriendSet()之后的逻辑:

我们遍历people并检查朋友集fSet是否更改。如果未检测到任何变化,则我们将返回fSet不变。另外,我们一直在寻找更多的朋友。

对于给定的密友组,例如上面的任何personList,如果组中的每个人都已经在fSet中,则无需更改fSet。这对应于.issuperset(.)支票。

否则,如果personList中至少有一个人已经在fSet中,那么通过关联,其他所有人也都必须在其中!我们分别使用.intersection(.).union()进行检查和实现。

每个人都是他们自己的朋友吗?

以上实现假定每个人都是他们自己的朋友。如果不需要这种行为,只需使用简单的if-guard和/或fSet.remove(.)就可以了。