I have a undirected circular graph of nodes, where the graph is made from a Graph
class, and the nodes are made from a Node
class. Each node has a few attributes, one of them being the pos
attribute. In the Graph class, I have initialized a graph
attribute which is a defaultdict. The graph
is meant to have nodes of the Node class, with each node pointing to its next and previous nodes based on pos
. If the node is 1, its previous node is the last node (let us consider it to have a pos
value of 20), and vice versa for the last node. For now I have set each key of graph
to have a value of None
, but I want to set the value as the neighbors, to indicate edges. Here is what I have done so far:
class Graph:
def __init__(self) -> None:
self.graph=defaultdict(Node)
for i in range(1,21):
self.graph[Node(i, False, False, False)]=None
def edge_gen(self):
for node in self.graph.keys():
if node.pos==1:
x=node
continue
if node.pos==50:
self.graph[node.pos].add(x)
self.graph[x].add(node.pos)
prev_node=self.graph.keys()[node.pos-1] # Here is where I am lost
print(prev_node, node)
self.graph[node.pos].add(prev_node)
self.graph[prev_node].add(node.pos)
return self.graph
As indicated by the comment, at that step, I don't understand how to get the object of the neighbor node of the current node based on pos
. I first tried to set prev_node
as node.pos-1
but I am aware that that won't work. I am putting the keys of graph
in a loop, and for each node, I want to add its previous node as a value, and the same for the previous node and the current node. Can someone please help me understand how to get the previous node in this loop to form the edges and therefore create a circular undirected graph? Thanks for reading.
CodePudding user response:
How do I reference a specific object based on its attribute, while it is in a loop, in Python?
If the object in a loop is delivered by an iterator you have in a loop code block access only to this one object. So the answer to your question above is: You can't reference a specific object based on its attribute while looping over an objects delivering iterator.
Having this question answered, my best guess about what you actually want to achieve with the code you provided is as follows:
class Node:
def __init__(self, pos, v1, v2, v3):
self.pos = pos
self.v1 = v1
self.v2 = v2
self.v3 = v3
class Graph:
def __init__(self, noOfNodes) -> None:
assert noOfNodes > 2
self.graph = {}
self.graph[1] = [
Node(noOfNodes , False, False, False),
Node( 2 , False, False, False), ]
for i in range(2, noOfNodes):
self.graph[i] = [
Node( i-1, False, False, False),
Node( i 1, False, False, False), ]
self.graph[noOfNodes] = [
Node(noOfNodes-1, False, False, False),
Node( 1 , False, False, False), ]
def edge_gen(self):
return self.graph
g = Graph(3)
print(g.edge_gen())
or
class Node:
def __init__(self, pos, v1, v2, v3):
self.pos = pos
self.v1 = v1
self.v2 = v2
self.v3 = v3
class Graph:
def __init__(self, noOfNodes) -> None:
assert noOfNodes > 2
self.noOfNodes = noOfNodes
self.listOfNodes = [None] # index 0 won't be used
for i in range(1, noOfNodes 1):
self.listOfNodes.append(Node(i , False, False, False))
self.graph = dict(zip(self.listOfNodes[1:], [None]*noOfNodes))
def edge_gen(self):
self.graph[self.listOfNodes[1]] = [
self.listOfNodes[self.noOfNodes],
self.listOfNodes[ 2 ] ]
for i in range(2, self.noOfNodes):
self.graph[self.listOfNodes[i]] = [
self.listOfNodes[i-1],
self.listOfNodes[i 1] ]
self.graph[self.listOfNodes[self.noOfNodes]] = [
self.listOfNodes[self.noOfNodes-1],
self.listOfNodes[ 1 ] ]
return self.graph
g = Graph(3)
print(g.graph)
print(g.edge_gen())
Hope this helps to get you off the dead end road of looking for a solution in the wrong direction.