簡體   English   中英

Python鏈表中的“ AttributeError”

[英]'AttributeError' in linked list in Python

此代碼處理從Python的鏈表中刪除重復項。 問題似乎出在remove功能上。

class Node(object):
  def __init__(self, data = None, next_node = None):
    self.next_node = next_node
    self.data = data

  #get data at that location

  def get_data(self):
    return self.data

  #get next element in linked list

  def get_next(self):
    return self.next_node

  #point to node specified by argument

  def set_next(self, new_next):
    self.next_node = new_next

class LinkedList(object):
  def __init__(self, head = None):
    self.head = head

  #insert element in linked list

  def insert(self, data):
    new_node = Node(data)
    new_node.set_next(self.head)
    self.head = new_node

  #remove duplicates

  def remove(self):
  #point to head
    current = self.head
    previous = None
    removed = False
  #variable to compare the current data with the rest
    new = current
    new = new.get_next()
  #while current is not None
    while current:
      if current.get_data() != new.get_data():
        previous = new
        new = new.get_next()
  #if same data, delete extra node from list
      else:
        removed = True
  #if only one element in list
        if previous is None:
          self.head = new.get_next()
        else:
          previous.set_next(new.get_next())
          new = new.get_next()
  #if 'new' reaches end of list, do this
      if new is None:
        current = current.get_next()
        previous = current
        new = current
        new = new.get_next()
    if not removed:
      print("No duplicates!")

  #print resulting linked list

  def print_result(self):
    current = self.head
    while current:
      print(current.get_data(), end = " ")
      current = current.get_next()

(我忽略了代碼的“函數調用”部分)。

while current:之后的第一個if語句中遇到屬性錯誤while current:remove函數中)說:

Traceback (most recent call last):
File "python", line 64, in <module>
File "python", line 26, in remove
AttributeError: 'NoneType' object has no attribute 'get_data'

我不明白哪個是None ,為什么。 任何幫助是極大的贊賞!

假設您對指數運行時間沒問題,那么一般方法看起來是正確的,但是有些細節會導致崩潰。 這是我發現的一對夫婦:

  1. 如果列表的長度為1, if current.get_data() != new.get_data():將崩潰,因為newNone

  2. 這些行:

     current = current.get_next() previous = current new = current new = new.get_next() # boom! 

    當您到達列表末尾時將崩潰。 current是最后一個節點,您得到下一個節點,即None ,然后嘗試進入None.get_next()

要解決這些問題,請一次遍歷列表中的每個節點,並在next每次檢查時檢查“ None ,以免崩潰。 取消鏈接也是如此:通過保持prev所在的位置並將prev.next_nodecurr設置為curr.next ,一次僅取消鏈接一個節點,然后在執行其他操作之前測試curr是否為None

這是一個簡單的工作版本:

def remove(self):
  curr = self.head

  while curr:
    runner = curr.next_node
    prev = curr

    while runner:
      if runner.data == curr.data:
        prev.next_node = runner.next_node
      else:
        prev = runner

      runner = runner.next_node

    curr = curr.next_node

想法是使用curr逐節點遍歷列表。 為每個節點創建一個runnerprev ,它將逐個節點遍歷列表節點的其余部分,並取消與curr匹配的所有節點的鏈接。

還有一種使用set的線性方法(速度的交易空間):

def remove_linear(self):
  seen = set()
  curr = self.head
  prev = None

  while curr:
    if curr.data not in seen:
      seen.add(curr.data)
      prev = curr
    else:
      prev.next_node = curr.next_node

    curr = curr.next_node

試試吧!

最后一點:Python通常不使用getter和setter; 它們增加了冗長性,並且不提供任何真正的保護,因此我在上面的代碼中省略了它們。 信任您的客戶端,並對“私有”變量使用下划線前綴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM