Python,RuntimeError:字典在迭代期间改变了大小

时间:2015-05-12 03:44:11

标签: python

我试图从给定的网络创建一种剩余网络,因为我首先创建了图中不存在的反向边缘,但我不断收到消息

RuntimeError: dictionary changed size during iteration

首先,我显然正在迭代在循环期间被修改的对象:

def Gf(Graph):    #residual graph
 for u in Graph:
    for v in Graph[u]:
        if u in Graph[v]: 
            pass
        else:
            Graph[v][u]=0 #create the edge with capacity 0
 return Graph

图表Graph是表单的对象(我是python的新手,所以我不知道这是否是最好的方法)

  

defaultdict(lambda:defaultdict(lambda:0))

将值[u] [v]设置为边u的容量,v。

所以我创建了一个Graph的副本并尝试迭代该对象

def Gf(Graph):    #residual graph
 Graph_Copy=Graph.copy()
 for u in Graph_Copy:
    for v in Graph_Copy[u]:
        if u in Graph_Copy[v]: 
            pass
        else:
            Graph[v][u]=0 
 return Graph

但那并没有奏效。我尝试了其他一些方法(创建一个深度复制;创建一个空对象Graph_Copy,迭代Graph然后设置足够的值到Graph_Copy)但到目前为止没有运气。我做错了什么?

2 个答案:

答案 0 :(得分:2)

老实说,我并不确切知道是什么导致了您的例外。然而,我所知道的是,使用嵌套字典来表示图形是一个坏主意。正如您所发现的那样,它们更难以迭代,并且具有更多的开销。相反,您应该使用嵌套列表。

如果我正确理解您当前的数据结构,可以表示如下:

graph = {
    u0: {v0: 0, v1: 0, ... },
    u1: {v0: 0, v1: 0, ... },
    ...
}  # the curly brackets denote dictionaries

更好的代表是:

graph = [
    [0, 0, 0, ...],
    [0, 0, 0, ...],
    ...
]  # the brackets denote lists

这是对图形的距离矩阵(http://en.wikipedia.org/wiki/Distance_matrix)表示进行编码的默认方式。如果您使用其他语言(如C / C ++)进行编码,那么这相当于二维数组。

假设u& v是图形顶点的标签,它们可以表示为数值,即第一个节点为0,第二个节点为1,依此类推。访问边u-v的值就像执行graph[u][v]一样简单。

现在,让我们假设您已经更改了代码,以便将具有N个顶点的图形G表示为大小为NxN的嵌套列表/ 2D数组,您的函数可以重写如下:

def gf(g):  # python style guideline recommends lower case variable & function names
    vertices_count = len(g)  # get the size of the original graph
    gf = []   # initialize the new redidual graph
    for u in range(vertices_count):
        gf.append([0]*vertices_count)  # initialize the edges
        for v in range(vertices_count):
            if g[u][v] > 0:
                # do something here if the value of edge u-v is more than zero, e.g. gf[u][v] = some formula
            else:
                # do something here if the value of edge u-v is zero,, e.g. gf[u][v] = 0
    return gf

答案 1 :(得分:0)

错误是因为您正在使用defaultdict。因此,看起来像只读操作(例如Graph[u])实际上可以添加密钥并更改字典大小。

编辑:删除了使用copydeepcopy

的建议