How to understand singly linked list in python and their in-place change?

guo*_*rui 0 python linked-list

What I want is: convert a give list, e.g. a = [3, 7, 5, 8], to a singly linked list.

Node definition:

class Node(object):
def __init__(self,val):
    self.val = val
    self.next = None
a = [3, 7, 5, 8]
Run Code Online (Sandbox Code Playgroud)

CODE-1:

## CODE-1
cur = dummy = Node(a[0])
for e in a[1::]:
    cur.next,cur = Node(e),cur.next
Run Code Online (Sandbox Code Playgroud)

CODE-2:

## CODE-2
cur = dummy = Node(a[0])
for e in a[1::]:
    cur.next = Node(e)
    cur = cur.next
# the following code outputs result
cur = dummy
while cur is not None:
    print(cur.val)
    cur = cur.next
Run Code Online (Sandbox Code Playgroud)

以上两段代码的输出

Question one: I know that CODE-2 outputs what I need, but I just wonder that why don't CODE-1 work? There must be something with it.

Question two: Is there any good method to help me better understand during next-time programming?


最后,为什么CODE-1不工作的原因是:(在CODE-1)时,首先e=7curNone。再其次,当e=5cur.next执行None.next,产生一个错误“类型”对象没有属性‘下一个’”。正是CODE-1发生的情况显示为

                       e = a[1]                                    e = a[2]
operation  Node(a[0])  cur.next,cur=Node(e),cur.next   then        cur.next,cur=Node(e),cur.next   
cur        3|pointer   None                            None        right-hand-side cur.next raises an error "NoneType has no attribute 'next' " and then exit   
cur.next   None        7|pointer                       (No definition)

Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 5

在分配,Python中检索右侧表达式值的第一,然后使用该值,使该分配。

所以

cur.next,cur = Node(e),cur.next
Run Code Online (Sandbox Code Playgroud)

存储Node(e)cur.next堆栈。cur.nextNone这里。下一步是分配两个值,因此cur.next分配了新节点,并cur分配了None

分配声明文档中

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

将表达式反汇编为字节码时,也可以看到以下内容:

>>> import dis
>>> dis.dis('cur.next,cur = Node(e),cur.next')
  1           0 LOAD_NAME                0 (Node)
              2 LOAD_NAME                1 (e)
              4 CALL_FUNCTION            1
              6 LOAD_NAME                2 (cur)
              8 LOAD_ATTR                3 (next)
             10 ROT_TWO
             12 LOAD_NAME                2 (cur)
             14 STORE_ATTR               3 (next)
             16 STORE_NAME               2 (cur)
             18 LOAD_CONST               0 (None)
             20 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

指令0、2和4执行Node(e),将其保留在堆栈上;指令6和8执行cur.next,将其保留None在堆栈上。ROT_TWO然后交换顶部的两个元素,所以Node(e)现在位于顶部,并且12和14将其分配给cur.next(从堆栈中清除),然后是16,存储None在中cur