Python实现赋值链的问题

时间:2013-04-16 19:16:09

标签: python python-2.7

我正在为教育Python库编写链接列表。以下是代码的重要摘要:

class Element(object):
  def __init__(self, value, next):
    self.value = value
    self.next = next

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

  def insert_back(self, element):
    if self.empty():
      self.insert_front(element)
    else:
      self.tail.next = Element(element, None)
      self.tail = self.tail.next
      # I'd like to replace the above two lines with this
      # self.tail = self.tail.next = Element(element, None)

我的问题来自最后一行。根据{{​​3}},Python对链式赋值的独特实现是罪魁祸首。

在其他语言中,最后一行与其上面的两行具有相同的效果,但Python首先计算表达式Element(element, None),然后从左到右分配结果,因此{{1} }在self.tail之前分配。这导致前一个tail元素没有引用新的tail元素,而新的tail元素引用它自己。

我的问题是:有没有办法用一个语句执行这两个作业?

我完全满足于使用更明确的两行分配;这只是为了好奇。

1 个答案:

答案 0 :(得分:5)

分配从不链接。

分配首先评估右手表达式,然后将结果从左到右依次分配给左手目标。

请参阅assigment statement documentation

  

赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)并将单个结果对象从左到右分配给每个目标列表。

所以你的代码:

self.tail = self.tail.next = Element(element, None)

实际上意味着:

result = Element(element, None)
self.tail = result
self.tail.next = result

您可以使用此功能,只需撤消分配顺序:

self.tail.next = self.tail = Element(element, None)

分配正确的顺序:

result = Element(element, None)
self.tail.next = result
self.tail = result

这会导致链接列表的正确行为:

>>> head = tail = Element(0, None)
>>> tail.next = tail = Element(1, None)
>>> head.value
0
>>> head.next
<__main__.Element object at 0x10262e510>
>>> head.next.value
1
>>> tail is head.next
True
>>> tail.next = tail = Element(2, None)
>>> tail is head.next.next
True