赋值链的 Python 实现问题 [英] Issue with Python implementation of assignment chaining

查看:30
本文介绍了赋值链的 Python 实现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一个教育性 Python 库编写一个链表.以下是重要的代码片段:

class 元素(对象):def __init__(self, value, next):self.value = 价值self.next = 下一个类链表(对象):def __init__(self):self.head = 无self.tail = 无def insert_back(self, element):如果 self.empty():self.insert_front(元素)别的:self.tail.next = 元素(元素,无)self.tail = self.tail.next# 我想用这个替换上面的两行# self.tail = self.tail.next = Element(element, None)

我的问题来自最后一行.根据这个问题的最佳答案,罪魁祸首是Python独特的链式赋值实现.

在其他语言中,最后一行与上面两行的效果相同,但 Python 首先计算表达式 Element(element, None) 然后将结果从左到右赋值- 对,所以 self.tail 被分配在 self.tail.next 之前.这会导致前一个 tail 元素不引用新的 tail 元素,而新的 tail 元素引用其自身.

我的问题是:有没有办法用一条语句完成这两个赋值?

我非常满意使用更明确的两行赋值;这只是为了好奇.

解决方案

分配从不链接.

赋值首先计算右边的表达式,然后将结果赋值给左边的目标,从左到右一个一个.

请参阅赋值语句文档:

<块引用>

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

所以你的代码:

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

实际上意味着:

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

你可以改用这个,只需颠倒分配顺序:

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

以正确的顺序分配:

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

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

<预><代码>>>>头 = 尾 = 元素(0,无)>>>tail.next = tail = 元素(1,无)>>>头值0>>>头.下一个<__main__.Element 对象在 0x10262e510>>>>头下一个值1>>>尾巴是头.下一个真的>>>tail.next = tail = 元素(2,无)>>>tail 是 head.next.next真的

I'm writing a linked list for an educational Python library. Here are the important snippets of code:

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)

My issue comes from the last line. According to the top answer to this question, Python's unique implementation of chained assignment is the culprit.

In other languages, the last line would have the same effect as the two lines above it, but Python evaluates the expression Element(element, None) first and then assigns the result from left-to-right, so self.tail is assigned before self.tail.next. This results in the previous tail element not referencing the new tail element, and the new tail element referencing itself.

My question is: is there a way to perform these two assignments with a single statement?

I'm perfectly content using the more explicit two-line assignment; this is just for curiosity's sake.

解决方案

Assignment is never chained.

Assignment first evaluates the right-hand expression, then assigns the result to the left-hand targets, one by one, from left to right.

See the assigment statement documentation:

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

So your code:

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

effectively means:

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

You could use this instead, simply reversing the assignment order:

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

which assigns in the correct order:

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

This results in the correct behaviour for a linked list:

>>> 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

这篇关于赋值链的 Python 实现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆