Python 迭代3个字典(关注速度)
我是Python新手,正在使用它构建图形 在我的脚本中,我有三个字典,它们可能需要相互嵌套:Python 迭代3个字典(关注速度),python,for-loop,dictionary,nested-loops,networkx,Python,For Loop,Dictionary,Nested Loops,Networkx,我是Python新手,正在使用它构建图形 在我的脚本中,我有三个字典,它们可能需要相互嵌套: dict1={'Node ID':1}->dict1={'0':1,'1':1,'2':1,…} dict2={'Node ID':G.neights(Node ID)}->dict2={'0':[1,2,4],…} dict3={'Node ID':Status}->dict3={'1':1,'2':0,'4':1} 非常清楚,dict1告诉我节点是活动的(1)还是失败的(0)[在这种情况下,dict
dict1={'0':1,'1':1,'2':1,…}
dict2={'0':[1,2,4],…}
dict3={'1':1,'2':0,'4':1}
dict1
告诉我节点是活动的(1)还是失败的(0)[在这种情况下,dict1
的所有节点都是活动的]dict2
包含连接到dict1
的每个节点的所有节点dict3
告诉我连接到dict1
的每个节点的所有节点是否都处于活动状态(1)或出现故障(0)
我的问题。我希望能够对节点之间的交互进行建模。这意味着,如果节点0
处于活动状态(status=1
),并且有3个节点连接到该节点,如果所有节点都失败(status=0
),则节点0
也会失败。如果只有一个连接的节点仍处于活动状态,则节点0
也仍处于活动状态
我的尝试。这是我设想的理论流程图,但我不知道如何将其转换为Python,也不知道这是否是最好的方法:
很抱歉,我没能把它转换成正确的代码,但我真的很挣扎。非常感谢 正如JoshRomRock在评论中所建议的,您可以创建如下类:
class Node(object):
def __init__(self, node_id, neighbours, status):
# neighbours could be a list of other Node objects
self.node_id = node_id
self.neighbours = neighbours
self.status = status
def neighbours_status(self):
# this method would return a list of tuples,
# where first tuple elem is node_id and the second is its status
return [(n.node_id, n.status) for n in self.neighbours]
my_nodes = set() # create set
my_nodes.add(Node(0, [], 1)) # add a node with no neighbours
# add some more nodes here ...
for node in my_nodes:
# do something with node.status, or node.node_id, or node.neighbours_status()
然后在代码中使用它,如下所示:
class Node(object):
def __init__(self, node_id, neighbours, status):
# neighbours could be a list of other Node objects
self.node_id = node_id
self.neighbours = neighbours
self.status = status
def neighbours_status(self):
# this method would return a list of tuples,
# where first tuple elem is node_id and the second is its status
return [(n.node_id, n.status) for n in self.neighbours]
my_nodes = set() # create set
my_nodes.add(Node(0, [], 1)) # add a node with no neighbours
# add some more nodes here ...
for node in my_nodes:
# do something with node.status, or node.node_id, or node.neighbours_status()
我想这可能是个问题。我不相信您尝试实施解决方案的方式是最好的,但我将尝试回答您提出的问题。您可能会问另一个参数稍宽的问题
以下是我认为您正在描述的伪代码:
initialize nodes
create some initial set_of_nodes such that all have status active.
for node in set_of_nodes:
if node has no neighbors:
move on
else:
has_active_neighbor = False
for neighbor in neighbors(node):
add neighbor to set_of_nodes
if neighbor's status is active:
has_active_neighbor = True
if has_active_neighbor = False:
node's status becomes inactive.
此代码存在一些潜在问题。您可以在迭代过程中迭代并更改某些节点的状态,这意味着如果再次检查某些已处理的节点,它们将失败。所以你看到的是某种瀑布。您可能希望在节点之间循环,直到不发生任何更改。而且,在循环过程中添加到集合中有点奇怪。这在Python中是一个禁忌(一般来说)。因此,我正在创建一组新的节点,您正在添加这些节点。因此,根据您试图研究的系统规则,这可能不是最好的。另外,我不明白为什么你只从一个子集开始,而不是从整个网络开始
下面是networkx的实现。我将循环使用它,直到没有变化发生
import networkx as nx
# code here to define graph, assign initial statuses, and create node_set
# node attributes can be defined in several ways (one appears below)
changes = True
while changes:
changes = False
added_nodes = set()
for x in node_set:
if G.degree(x)==0 or G.node[x]['status'] == 'failed':
continue #nothing to see here, move on.
else:
has_active_neighbor=False
for neighbor in G.neighbors(x):
added_nodes.add(neighbor) #put it here even if it is already in node_set
if G.node[neighbor]['status'] == 'active':
has_active_neighbor = True
break
if not has_active_neighbor:
changes = True
G.node[x]['status'] = 'failed'
if node_set.difference(added_nodes): #True if any new nodes:
node_set = node_set.union(added_nodes)
changes = True
#everything is done now - here's the dictionary of statuses:
statuses = nx.get_node_attributes(G, 'status')
您不必在3个DICT上循环,因为它们为您提供了对其值的直接访问。您只需要在dict1密钥集中进行迭代。但是你的主要问题是,你可以用一组对象做你想做的事情。谢谢!你能帮我做个“实验”吗?我发现字典里有很多可能的地雷……你有没有试着设置一个节点类,其中包含节点id、邻居(作为节点列表)和状态字段?将它们放在一个集合中,并对其进行迭代以应用您的规则。备注:我不了解NetworkX,因此我不确定您想要的输出。请忘记
NetworkX
,我提到它只是想了解这个问题的来源。我真的不知道如何创建类,因为我对Python非常陌生。你能详细说明一下吗?如果你使用networkx,大部分都会自动处理。。。它将为您提供图形和所有节点。您可以指定任意节点属性。谢谢。顺便说一句,我不知道如何在我的情况下使用它。我不需要添加节点-我已经有10000个节点了。另外,您定义的my_nodes=set()
是我从未见过的……为了使用类解决方案,您必须首先将节点的表示转换为该表示,然后您将受益于轻松迭代的能力。对于循环,它也比使用嵌套的更快。这就是我建议添加它们的原因。关于集合
,您可能想看看这里:几个问题:您将如何使用节点
类?你怎么称呼它?类需要的对象是什么?它在三行中做了什么?对不起,这似乎很难理解…@pzelasko这和我昨天的意思很接近,谢谢。我没来得及把它写好。@Francesco Castellani我会尽力回答你们的问题。使用节点
类时,应首先将这3个词典中的当前表示形式转换为节点
对象的集合(或列表)。您可以以类似于我在第二个代码块的第二行中所做的方式创建节点
对象。要使用其成员,只需编写Node.member
;请参阅我在答案中的最后一条评论。对象
是节点类的父类,如果您想要一个“新样式”对象,则需要在Python2中指定该节点类(尽管这是一个与此问题无关的细节)。希望能有帮助。谢谢!我认为关于已经处理的节点的问题不是一个真正的问题。我