为了账号安全,请及时绑定邮箱和手机立即绑定

为什么当我在集合中切换顺序时我的代码采用不同的值

为什么当我在集合中切换顺序时我的代码采用不同的值

牧羊人nacy 2021-10-10 15:31:24
我正在尝试实现一种返回图形边缘的方法,由邻接列表/字典表示。所以要遍历字典,首先我遍历键,然后遍历存储在相应键中的每个值。在嵌套的 for 循环中,我有一个条件,如果特定的边,比如说 (a,b) 不在边的集合中,那么将它添加到集合中——否则通过。在我第一次运行时,该方法采用了相同的边——也就是说,在边的集合中,有 (a,b) 和 (b,a)。class Graph():    def __init__(self, grph={}):        self.graph = grph    def get_vertices(self):        for keys in self.graph:            yield keys    def get_edges(self):        edges = set()        for key in self.graph:            for adj_node in self.graph[key]:                if (key, adj_node) not in edges:                    edge = (key, adj_node)                    edges.add(edge)                else:                    pass        return edgesdef main():    graph1 = {        'A': ['B','C','D'],        'B': ['A','E'],        'C': ['A', 'D'],        'D': ['A', 'C'],        'E': ['B'],    }    graph_one = Graph(graph1)    print(list(graph_one.get_vertices()))    print(graph_one.get_edges())if __name__ =='__main__':    main()输出是:{('A','B'),('D','A'),('B','A'),('B','E'),('A','D') ,('D','C'),('E','B'),('C','D'),('A','C'),('C','A') }所以我所做的是,我只是改变了 if 语句:“if (adj_node, key) not in edge:”def get_edges(self):        edges = set()        for key in self.graph:            for adj_node in self.graph[key]:                if (adj_node, key) not in edges:                    edge = (key, adj_node)                    edges.add(edge)                else:                    pass        return edges现在输出是:{('C','D'),('A','B'),('E','B'),('A','C'),('A','D') }我很好奇为什么会这样,如果你们能向我解释一下,我将非常感激。提前致谢!
查看完整描述

2 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

我认为它只需要一点点改变,试试这个:


def get_edges(self):

    edges = set()

    for key in self.graph:

        for adj_node in self.graph[key]:

            if ((key, adj_node) not in edges) and ((adj_node, key) not in edges):

                edge = (key, adj_node)

                edges.add(edge)

            else:

                pass

    return edges

更新:

所以它是一个Undigraph。

是我把它搞得太复杂了。

你的方式实际上比我检查两种方式都要好。


您的代码成功的原因是set它只包含任何值的一个实例。

所以每次执行add,如果已经存在相同的元组,它就不会改变集合。

并且您已经使用if来检查相反方向的元组,因此它不会创建重复的边。


例如,当(a, b)命中if检查时,它会检查(b,a)集合中是否存在,如果存在,则通过。如果不是,则在集合中添加 (a, b),如果 (a, b) 存在,则集合不会改变,因为集合中只有一个实例。

稍后当循环到 (b, a) 时,因为 (a, b) 已经在集合中,所以if将是假的并通过。

所以通过这种方式,集合是安全的,没有重复的边。


查看完整回答
反对 回复 2021-10-10
  • 2 回答
  • 0 关注
  • 183 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信