Python 中链表的指针



我在python中创建了一个链表,并创建了一个指向同一节点的指针变量。

但是,当我尝试更新指针时,链表不会更新。 它仅在我使用原始符号时更新。 以下是关注的三行,然后是代码片段:

pointer = self.storage[index]
pointer = pointer.next #does not work
self.storage[index] = self.storage[index].next #DOES work.
def remove(self, key):
pair = LinkedPair(key,None)
index = self._hash_mod(pair)
pointer = self.storage[index]
prev = None
while pointer:
if pointer.key == pair.key:
if prev is None:  #at the beginning of the linked list, set the head to equal the next value
print(self.storage[index] == pointer) #true
self.storage[index] = self.storage[index].next
pointer = pointer.next
# pointer = pointer.next
break
# self.display(pointer,prev,' pointer == pair')
prev.next = pointer.next
del pointer
break
else:
prev = pointer
pointer = pointer.next
# self.display(pointer,prev,' post shifting')
# self.storage[index] = self.storage[index].next
return -1

python 中的变量只是对象的名称,分配给它们只会更改由该名称指定的对象。

但是,当指派给列表的元素时,您将更改列表中该位置所引用的对象。

因此:

pointer = self.storage[index] # 1
pointer = pointer.next  # 2
self.storage[index] = self.storage[index].next  # 3

(1( 使pointer成为在storage[index]引用的对象的名称

(2(在赋值=的右侧,查找pointer引用对象的name属性。这是self.storage[index].name.赋值将使pointer变量引用self.storage[index].name。要更新self.storage列表,您需要对列表对象本身进行操作。相反,pointer所引用的self.storage[index]只是"某个对象"。您甚至无法从那里返回列表,因此无法在此处更改列表。

(3(但是,在这里,您正在更改列表self.storage,此时替换index. You could have doneself.storage[index] = pointer'处的元素,具有相同的效果。

当然,python 在引擎盖下使用引用(或指针(。my_list[1] = obj没有为obj分配空间,它会存储对它的引用。但是局部变量和全局变量不是引用,它们是名称。

最后,全局和局部命名空间只是将变量名称映射到对象。它们通常只是普通的字典。您可以通过调用globals()locals()来查看这些内容。或者,您可以通过更改该字典来"实现"变量赋值:

foo = 1
globals()["foo"] = 2
print(foo)  # --> 2

Python 对变量的赋值不同于对可变对象(如列表或字典(的赋值。让我们考虑以下语句:

a = 1     # 1
b = [1]   # 2
b[0] = 2  # 3

前两个作业也在做同样的事情。它们正在创建(或更新(ab的全局变量,并分别将它们映射到int对象1list对象[1]。您将拥有:

globals()
{
...
"a": 1,
"b": [1]
...
}

第三个任务完全不同。这种类型的赋值实际上是由左侧的对象实现的。从文档中:

当目标是可变对象(属性引用、订阅或切片(的一部分时,可变对象最终必须执行赋值并决定其有效性,并且如果赋值不可接受,则可能会引发异常。

这意味着第三条语句由列表对象本身实现。现在 python 中的列表保留对对象的引用(它不会复制对象(。b[0]在表达式中使用时,由列表对象的特殊方法实现,并将返回列表引用的位置 0 的对象。b[0] = 2实际上是调用列表对象的特殊方法,将索引 (0( 和目标对象 (2( 作为参数,列表实现决定它如何更新自身:它将索引 0 处的引用更改为新对象。

这种差异嵌入在python的赋值语句中。我也喜欢你的完整参考资料。

更多详情:

  • https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/
  • https://docs.python.org/3/tutorial/classes.html#a-word-about-names-and-objects
  • https://docs.python.org/2.0/ref/assignment.html

相关内容

  • 没有找到相关文章

最新更新