【问题标题】:Python thinks object instance is list objectPython 认为对象实例是列表对象
【发布时间】:2015-11-07 04:23:03
【问题描述】:

所以我在 Graph 上实施 BFS 以检测所有周期。我通过邻接列表实现了图表。但是当我运行我的代码时,我收到以下错误

    Traceback (most recent call last):
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 228, in   <module>
    main()
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 223, in main
    traverse(g.getVertex(2))
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 168, in traverse
   while (x.getPred()):
   AttributeError: 'list' object has no attribute 'getPred'

所以当我调用 traverse() 函数时就会出现问题。 这是我的主要功能

def main():    

     g = Graph()

     for i in range(1,9):

          g.addVertex(i)

     g.addEdge(1,2)
     g.addEdge(1,4)
     g.addEdge(1,8)
     g.addEdge(2,3)
     g.addEdge(2,1)
     g.addEdge(3,2)
     g.addEdge(3,4)
     g.addEdge(3,7)
     g.addEdge(3,8)
     g.addEdge(4,1)
     g.addEdge(4,3)
     g.addEdge(4,5)
     g.addEdge(5,4)
     g.addEdge(5,6)
     g.addEdge(5,7)
     g.addEdge(6,5)
     g.addEdge(6,7)
     g.addEdge(7,3)
     g.addEdge(7,6)
     g.addEdge(7,5)
     g.addEdge(8,3)
     g.addEdge(8,1)

     for v in g:

          for w in v.getConnections():

               print("(%s,%s)"%(v.getId(),w.getId()))




     print("\nDoing BFS...")

     bfs_tree(g,g.getVertex(1))

     a = g.getVertex(2)

     print(type(a))

     traverse(g.getVertex(2))




main()

这里是遍历函数:

def traverse(y):

     x = y


     while (x.getPred()):
          print(x.getId())

          x = x.getPred()
     print(x.getId())

这里是图的邻接表实现:

class Graph:

      def __init__(self):

           self.vertList = {}  #this is the masterlist
           self.numVertices = 0

      def addVertex(self,key): #turn something into a Vertex object

           self.numVertices = self.numVertices + 1

           newVertex = Vertex(key)

           self.vertList[key] = newVertex #maps vertex names to vertex objects

           return newVertex

      def getVertex(self,n):

           if n in self.vertList:

           return self.vertList[n] #returns the Vertex object
      else:

           return None

      def __contains__(self,n):#tweak the built-in operator 'in'(containment check)

           return n in self.vertList

      def addEdge(self,f,t,cost = 0):

           if f not in self.vertList: #if f is not a node in the graph

                nv = self.addVertex(f)

           if t not in self.vertList:     #if t is not a node in the graph

                nv = self.addVertex(t)

                self.vertList[f].addNeighbor(self.vertList[t], cost)

      def getVertices(self):

           return self.vertList.keys()

      def __iter__(self): # iterate over Vertex objects over the Graph

           return iter(self.vertList.values())
class Vertex:

     def __init__(self,key):

           self.id = key
           self.connectedTo={} #dictionary which contains all the other vertices it is connected to
           self.pred = [] #for BFS tree / a list because we are dealing with cycles
           self.color = "white" #for BFS tree


      def addNeighbor(self,nbr,weight=0):

           self.connectedTo[nbr] = weight #nbr is another Vertex object 

      def __str__(self):

           #TODO: lookup how that for loop works
           return str(self.id) + "connected to " + str([x.id for x in self.connectedTo])

      def getConnections(self):

           return self.connectedTo.keys()

      def getId(self):

           return self.id

      def getWeight(self,nbr):

           return self.connectedTo[nbr]

      def getColor(self):

           return self.color

      def setColor(self,color):

           self.color = color

      def setPred(self,node):

           self.pred.append(node)

      def getPred(self):

           if len(self.pred)>1:
                return self.pred
           elif len(self.pred) == 0:

                return self.pred[0]
           else:

                return self.pred

为什么说 g.getVertex(2) 是一个列表对象?我很确定它是一个 Vertex 对象。我什至打印出了 main 函数中的类型,它说它是一个实例而不是列表对象。

【问题讨论】:

  • 您在“x = x.getPred()”处将 x 更改为另一个对象/类型。它变成 getPred() 返回的任何东西。
  • 如果len(self.pred) == 0 为真,那么self.pred[0] 将引发IndexError。除此之外,Python 不仅认为 x 是一个列表,它知道 它是一个列表。在您的代码中的某处,x.getPred() 返回一个列表。
  • 你从x.getPred()返回self.pred(一个列表),所以设置x = x.getPred() 显然x设置为一个列表,之后x.getPred()将失败.
  • 哦,我明白了。非常感谢!!!

标签: python graph breadth-first-search


【解决方案1】:

您在此处将x 替换为x.getPred() 的结果:

 while (x.getPred()):
      print(x.getId())
      x = x.getPred()

x.getPred() 返回self.pred

  def getPred(self):

       if len(self.pred)>1:
            return self.pred
       elif len(self.pred) == 0:

            return self.pred[0]
       else:

            return self.pred

(请注意,对于len(self.pred) == 0,您尝试返回self.pred[0],这将引发IndexError 异常)。

self.pred 是一个列表:

class Vertex:
     def __init__(self,key):
           # ...
           self.pred = [] #for BFS tree / a list because we are dealing with cycles

所以您将x 替换为list 对象,然后循环返回 并在该列表对象上调用x.getPred()

【讨论】:

    【解决方案2】:

    x = x.getPred() 是问题所在。 while 循环中的第一次检查很好,但在第一次更新 x 后它会中断,然后重新检查。

    正如实现的那样,getPred 正在返回 self.pred(它从 self.pred 返回一个 而不是整个事情的唯一情况被破坏了;长度为 0,并且您索引,所以它会引发IndexError)。 self.predlist

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-06
      • 2013-03-02
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      相关资源
      最近更新 更多