简体   繁体   中英

How are these two different?

def reverseList(self, head):
    
    prev, curr = None, head
    while curr:
        curr.next, prev, curr = prev, curr, curr.next
    return prev

I don't get the difference between this one above and

def reverseList(self, head):
    
    prev, curr = None, head
    while curr:
        curr.next = prev
        prev = curr
        curr = curr.next
    return prev

Why do they have different results? I thought the way of first one and second ones' declaration are same.

In the first function, curr is assigned the old value of curr.next , while in the second function, curr is assigned the new value of curr.next (aka prev ).

In the first code, when the curr = curr.next is executed, curr.next was whatever value it was before the "multi-assign" statement.

In the second code, when curr = curr.next is executed, curr.next has the value that prev had, by virtue of the curr = prev statement executed earlier.


If you want to run the 3-line code with a "multi-assign" statement, you should use:

curr.next, prev, curr = prev, curr, prev

This can be easily shown with a helper ListNode class (I use next_ because next is a reserved word in Python):

class ListNode:   
    def __init__(self, name=None, next_=None):
        self.name = name
        self.next_ = next_
    
    def __str__(self):
        return f'ListNode[{self.name}->{self.next_}]'

    
prev, curr = ListNode('P'), ListNode('C')
print(prev, prev.next_, curr, curr.next_)
curr.next_ = prev
prev = curr
curr = curr.next_
print(prev, prev.next_, curr, curr.next_)
# ListNode[P->None] None ListNode[C->None] None
# ListNode[C->ListNode[P->None]] ListNode[P->None] ListNode[P->None] None


prev, curr = ListNode('P'), ListNode('C')
print(prev, prev.next_, curr, curr.next_)
curr.next_, prev, curr = prev, curr, prev
print(prev, prev.next_, curr, curr.next_)
# ListNode[P->None] None ListNode[C->None] None
# ListNode[C->ListNode[P->None]] ListNode[P->None] ListNode[P->None] None

They switch value in first approach but in second it assigns variables to each other.

Its because in the first line of code, all the assigning is executed at once using the original values

In the second case, when you assign curr.next to curr, curr.next is already equal to prev as assigned before. So curr gets the value of prev in the end unlike the first approach, where all of them get the original values

class X:
    def __init__(self, value):
        self.value = value
        self.next = None

head = X(1)
head.next = X(2)
head.next.next = X(3)
head.next.next.next = X(4)
head.next.next.next.next = X(5)

prev, curr = None, head

while curr:
    tmp = curr.next #Here...
    curr.next = prev
    prev = curr
    curr = tmp #and here.
    
while prev:
    print(prev.value)
    prev = prev.next

For the second example (ie without variable exchanging), you need a temporary variable to store the value of curr.next .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM