python - What is the difference when assigning an object like a LinkedList to a variable versus an array? - Stack Overflow

I was working on this problem from HackerRank trying to insert an element at the tail of a linked list

I was working on this problem from HackerRank trying to insert an element at the tail of a linked list and I have to return the head of the node.

def insertNodeAtTail(head, data): 
    if head is None: 
        head = SinglyLinkedListNode(data) 
        return head 
    current_head = head 
    while current_head.next: 
        current_head = current_head.next 
    current_head.next = SinglyLinkedListNode(data)
    return head

SinglyLinkedListNode is a class for creating nodes with 2 methods: data which gives value to the node, and next which allows us to move on to the next node.

The code above works but my understanding is, if we mess or tweak with current_head, the changes will appear on head too (because that's how assigning works in Python). But the code is working perfectly. If I use return current_head, the answer is wrong. I did something similar such as

a = [1,2,3,4,5,6]
b = a
for i in range(5):
    b.append(i)

And both array a and array b are identical and prints [1,2,3,4,5,6,0,1,2,3,4]. I'd appreciate any help I can get please. This inconsistency is messing with my head because the idea for inserting at the end of the tail is clearly easy but I keep getting worried about having to return the head of the node (and I can't do that if I keep misunderstanding whether I am changing anything to the LL).

Thank you in advance!

I was working on this problem from HackerRank trying to insert an element at the tail of a linked list and I have to return the head of the node.

def insertNodeAtTail(head, data): 
    if head is None: 
        head = SinglyLinkedListNode(data) 
        return head 
    current_head = head 
    while current_head.next: 
        current_head = current_head.next 
    current_head.next = SinglyLinkedListNode(data)
    return head

SinglyLinkedListNode is a class for creating nodes with 2 methods: data which gives value to the node, and next which allows us to move on to the next node.

The code above works but my understanding is, if we mess or tweak with current_head, the changes will appear on head too (because that's how assigning works in Python). But the code is working perfectly. If I use return current_head, the answer is wrong. I did something similar such as

a = [1,2,3,4,5,6]
b = a
for i in range(5):
    b.append(i)

And both array a and array b are identical and prints [1,2,3,4,5,6,0,1,2,3,4]. I'd appreciate any help I can get please. This inconsistency is messing with my head because the idea for inserting at the end of the tail is clearly easy but I keep getting worried about having to return the head of the node (and I can't do that if I keep misunderstanding whether I am changing anything to the LL).

Thank you in advance!

Share Improve this question asked Mar 26 at 22:34 gradstudent1995gradstudent1995 1051 silver badge 1
  • 1 b = a does not make a copy of a. It's just another reference to the same list. See nedbatchelder/text/names.html. – chepner Commented Mar 26 at 23:03
Add a comment  | 

2 Answers 2

Reset to default 2

current_head only points to head if it is the only node in the list, and yes, modifying it at that point would appear when viewing head, but current_head moves to locate the last node in the list.

Example:

After current_head = head, both names refer to the same object:

+------+
| data |<---- head <---- current_head
| next |--\
+------+  |
          |
+------+  |
| data |<-/
| next |----> None
+------+

After while current_head.next: current_head = current_head.next, current_head is re-assigned to point to the object that current_head.next refers to, and that continues as long as current_head.next doesn't refer to None:

+------+
| data |<---- head
| next |--\
+------+  |
          |
+------+  |
| data |<-/ <---- current_head
| next |----> None
+------+

Now current_head refers to the last node in the list, no matter how many nodes were in the list.

After current_head.next = SinglyLinkedListNode(data), the last node is modified to refer to a new object:

+------+
| data |<---- head
| next |--\
+------+  |
          |
+------+  |
| data |<-/ <---- current_head
| next |--\
+------+  |
          |
+------+  |
| data |<-/
| next |----> None
+------+

If you return current_head at this point, it would lose the first node. return head is correct because it still points to the first node in the list.

A better name would be current_node instead of current_head.

The difference between the two scenarios is that in the first you have a loop that assigns something different to current_head in each iteration, while in the second scenario you don't -- b doesn't get assigned(!) something different.

We could alter the second scenario by actually doing an assignment to b. To achieve that, we could make the list a nested list:

a = [None]
b = a
for i in range(5):
    b[0] = [None]
    b = b[0]
    
print(a)
print(b)

Now we have an assignment to b, which gives us a more consistent comparison with the first scenario (of the linked list). And now we see that a and b are different, as the output produced is:

[[[[[[None]]]]]]
[None]

So a references the whole structure that was created, while b only references the last entry that was created inside it. This is quite similar how in the first scenario head references the whole structure that was created and current_head (despite its name), right after the loop, references the last node that was created before adding another one.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744122703a4559474.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信