我正在用Python编写LinkedList
的实现。在remove
函数中,该函数按索引删除项目。删除列表中的第一个节点时,发现一个local variable is not used
问题:
class LinkedList:
def __init__(self, nodes=None):
self.head = None
def remove(self, index):
pre_node = self.head
if index == 0:
self.head = self.head.next
# next line doesn't work
# pre_node = self.head.next
return
for idx, cur_node in enumerate(self):
if idx == index-1:
pre_node = cur_node
if idx == index:
pre_node.next = cur_node.next
return
raise Exception('index out of range')
def __iter__(self):
node = self.head
while node is not None:
yield node
node = node.next
def __str__(self):
node = self.head
nodes = []
while node is not None:
nodes.append(node.data)
node = node.next
nodes.append("None")
return '->'.join(nodes)
class Node:
def __init__(self, data):
self.data = data
self.next = None
if __name__ == '__main__':
first_list = LinkedList()
first_node = LinkedList.Node('0')
first_list.head = first_node
second_node = LinkedList.Node('1')
first_node.next = second_node
third_node = LinkedList.Node('2')
second_node.next = third_node
first_list.remove(0)
print(first_list)
假设列表是0->1->2->None
的种类,则在调用a_list.remove(0)
时,它应返回1->2->None
。上面带有语句self.head = self.head.next
的代码运行良好,而self.head = pre_node.next
也运行良好,但是pre_node = pre_node.next
和pre_node = self.head.next
因pre_node is not used
失败,该函数返回了原始清单。我很困惑,为什么代码应该只在赋值左侧的self.head
而不是pre_node
正确,即使我们在此之前做pre_node = self.head
。
答案 0 :(得分:1)
一个局部变量(如pre_node
)仅存在,直到您从函数return
开始。所以在这段代码中:
self.head = self.head.next
pre_node = self.head.next
return
第pre_node = self.head.next
行没有任何用处,因为您设置的变量会在返回时消失。这实际上并不会导致程序失败,但是linters和IDE会在看到类似这样的内容时向您发出警告,因为这表明您错过了某些内容(例如,您打算将其设置为实例变量,或者您打算进行其他操作)具有该值)。
在这种情况下,您已经完成了删除节点所需的操作,即重新分配self.head
。由于pre_node = self.head.next
行不执行任何操作,因此您可以在不更改程序工作方式的情况下将其删除。这里没有真正的问题(至少对于index == 0
而言)。
使用局部变量的地方将是引用列表中需要修改的其他节点的一种方式。例如:
def remove(self, index):
"""Remove the node with the given index.
Raises AttributeError if the index is out of range."""
if index == 0:
# Move self.head pointer up one to remove head node.
self.head = self.head.next
return
# Find node before the one with the given index.
pre_node = self.head
for _ in range(index-1):
pre_node = pre_node.next
# Remove pre_node.next by skipping over it.
pre_node.next = pre_node.next.next
在此代码中,pre_node
引用了列表中的特定节点,您可以通过重新分配pre_node.next
来对其进行修改。函数完成后,变量pre_node
本身并不重要,但是它引用的节点是列表的一部分,因此重新分配pre_node.next
会对列表产生影响,其方式为重新分配{{ 1}}本身就没有。