![](/img/trans.png)
[英]AttributeError in the implementation of queue by using Single Linked List in the python
[英]'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, if current.get_data() != new.get_data():
將崩潰,因為new
為None
。
這些行:
current = current.get_next() previous = current new = current new = new.get_next() # boom!
當您到達列表末尾時將崩潰。 current
是最后一個節點,您得到下一個節點,即None
,然后嘗試進入None.get_next()
。
要解決這些問題,請一次遍歷列表中的每個節點,並在next
每次檢查時檢查“ None
,以免崩潰。 取消鏈接也是如此:通過保持prev
所在的位置並將prev.next_node
和curr
設置為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
逐節點遍歷列表。 為每個節點創建一個runner
和prev
,它將逐個節點遍歷列表節點的其余部分,並取消與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.