The short answer to this is that, Python is a pass-by-object-reference language, not pass-by-reference as implied in the question. It means that:

  1. result and result_tail are two variables that happen to point at the same value
  2. Mutation / Changing of the underlying value (result_tail.next = ListNode(1)) will affect the value shown by result
  3. However, assigning / pointing the variable result_tail to another value will NOT affect the value of result
  4. result_tail = result_tail.next is assigning the next node of the node that is currently assigned by the variable

The following is an visualization of the values that are assigned to the variables (r = result, rt = result_tail):

result = ListNode(0)
#r
#0 -> None

result_tail = result
#r
#0 -> None
#rt

result_tail.next = ListNode(1)
#r
#0 -> 1 -> None
#rt

result_tail = result_tail.next
#r
#0 -> 1 -> None
#     rt

result_tail.next = ListNode(2)
#r
#0 -> 1 -> 2 -> None
#     rt

result_tail = result_tail.next
#r
#0 -> 1 -> 2 -> None
#          rt

References for additional reading:

  • An article explaining the Python pass-by-object reference style in detail https://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/
  • An answer explaining Python's pass-by-object reference style https://stackoverflow.com/a/33066581/12295149
  • Question asking on Python's object reference style Understanding Python's call-by-object style of passing function arguments
Answer from Joseph on Stack Overflow
🌐
LeetCode
leetcode.com › problems › linked-list-random-node
Linked List Random Node - LeetCode
Linked List Random Node - Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen. Implement the Solution class: * Solution(ListNode head) Initializes the object with the head of the singly-linked list head...
🌐
Reddit
reddit.com › r/learnprogramming › help me understand the listnode structure from leetcode [c++]
r/learnprogramming on Reddit: Help me understand the ListNode structure from LeetCode [C++]
December 22, 2020 -

I know it's a dumb question, but I would like to know how the structure works and what does each line does / works. Also, when solving problems from LeetCode I like to write and test the code on my own machine, so I would also like to know how to create one of those structures with my own values.

Here's the structure that is shown in LeetCode:

struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
};

Also, here's a link to the problem in case it helps.

Thanks in advanced.

Top answer
1 of 2
2
A listNode holds an integer and a pointer to another listNode. Since each node can hold a reference to the next node and that node can hold a reference to the next node, and so on, it allows you to create a list that can be added to and removed from dynamically as needed. The three constructors allow you to specify no parameters (the node defaults to holding 0 and null) just the int parameter, or both the value and next parameters.
2 of 2
1
I am going to explain it, but realize that if you have never even worked with linked lists before it will be pretty hard to solve leetcode problems using them. I would recommend learning about linked lists first, this video seems pretty good : https://www.youtube.com/watch?v=WwfhLC16bis . That ListNode structure contains 5 things : an int so that the node can store data, a pointer which can be used to connect this node to another one (called next in this case), and 3 different constructors. You can spot a constructor in most languages because it has the same name than the class/struct it's in (at least for C++ and Java). It's just a function that allows you to actually build that object when you need to later. There are 3 different versions here to allow you to build a ListNode with its value and pointer already determined, or not depending on what you need. To populate a linked list the lazy way, I recommend starting from the end. Say you want a list such as 1->2->3, you first create a node which contains 3 and doesn't point anywhere. Then you create a node which contains 2 and points to the node we just made. Then you make a node which contains 1 and points to the previous one. Now the node that contains 1 is the "head" of your linked list. But since you are learning linked list for the first time, I highly recommend making a function to create the linked list for you instead from an array, because you will learn more by doing this, and it will allow you to then create lists much more quickly if you want to test different things out. Such a function could look like this : ListNode createLinkedList( *insert array here* ) { *your code here* } and you would call it by making an int array and passing it as an argument like this : int coolArray[3] = { 1, 2, 3 }; ListNode quickAssNode = createLinkedList( coolArray);
🌐
Reddit
reddit.com › r/learnprogramming › how does listnode work in leetcode?
r/learnprogramming on Reddit: How does ListNode work in LeetCode?
July 3, 2024 -

I've decided to tackle my first medium problem on Leetcode, Add Two Numbers (Java), but I've hit a wall. I started by reading the task and looking at the description, but after doing some research I just can't grasp how the ListNode class works. Here is its code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */

I understand that it is supposed to work similar to the java.util.LinkedList class, but I don't get how. It holds two methods besides the default constructor and they only seem to set the values of int val and ListNode next. I am lost at how this chunk of code creates a singly-linked list, as I learned how to use one, but not how it works under the hood. I thought maybe it had something to do with the keyword "this", but after researching even more I learned that it is used to refer to the class property and not the parameter.

Also, while I was working on this I also wondered, is there a way to check the class files for the standard library or any other library? I want to check the code for the LinkedList and other classes in the future for clarity.

Top answer
1 of 4
27

The short answer to this is that, Python is a pass-by-object-reference language, not pass-by-reference as implied in the question. It means that:

  1. result and result_tail are two variables that happen to point at the same value
  2. Mutation / Changing of the underlying value (result_tail.next = ListNode(1)) will affect the value shown by result
  3. However, assigning / pointing the variable result_tail to another value will NOT affect the value of result
  4. result_tail = result_tail.next is assigning the next node of the node that is currently assigned by the variable

The following is an visualization of the values that are assigned to the variables (r = result, rt = result_tail):

result = ListNode(0)
#r
#0 -> None

result_tail = result
#r
#0 -> None
#rt

result_tail.next = ListNode(1)
#r
#0 -> 1 -> None
#rt

result_tail = result_tail.next
#r
#0 -> 1 -> None
#     rt

result_tail.next = ListNode(2)
#r
#0 -> 1 -> 2 -> None
#     rt

result_tail = result_tail.next
#r
#0 -> 1 -> 2 -> None
#          rt

References for additional reading:

  • An article explaining the Python pass-by-object reference style in detail https://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/
  • An answer explaining Python's pass-by-object reference style https://stackoverflow.com/a/33066581/12295149
  • Question asking on Python's object reference style Understanding Python's call-by-object style of passing function arguments
2 of 4
16

For those reading this in the future: I wanted to debug linked list problems on a local environment so here is what I did.

  1. Modified the Leetcode code for ListNode by including the dunder "repr" method. This is for when you want to print a ListNode to see what its value and next node(s).
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

    def __repr__(self):
        return "ListNode(val=" + str(self.val) + ", next={" + str(self.next) + "})"
  1. Next, I made a recursive function that makes a nested ListNode when you pass in a list. This is so you can test your methods by passing in lists (instead of having to manually make a confusing looking ListNode yourself.
def list_to_LL(arr):
    if len(arr) < 1:
        return None

    if len(arr) == 1:
        return ListNode(arr[0])
    return ListNode(arr[0], next=list_to_LL(arr[1:]))
  1. Here is an example that tests my answer for the "reverseList" problem:
def reverseList(head: ListNode) -> ListNode:
    prev = None
    while head:
        next_node = head.next
        head.next = prev
        prev = head
        head = next_node

    return prev


# test cases
t1 = list_to_LL([1, 2, 3, 4, 5])  #ListNode(val=1, next={ListNode(val=2, next={ListNode(val=3, next={ListNode(val=4, next={ListNode(val=5, next={None})})})})})
t2 = list_to_LL([1, 2])  #ListNode(val=1, next={ListNode(val=2, next={None})})
t3 = list_to_LL([])

# answers
print(reverseList(t1))
print(reverseList(t2))
print(reverseList(t3))
🌐
LeetCode
leetcode.com › problems › add-two-numbers › discuss › 174970 › Help-with-ListNode-(Python)
Help with ListNode (Python) - Add Two Numbers
Can you solve this real interview question? Add Two Numbers - You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit.
🌐
LeetCode
leetcode.com › discuss › general-discussion › 388183 › improving-listnode-definition-for-python-problems
Improving ListNode definition for python problems - Discuss - LeetCode
This definition initialise a listnode without a next value, it is very clunky to use in recursion class ListNode: def init(self, x): self.val = x
🌐
GitHub
github.com › interviewcoder › leetcode › blob › master › src › com › leetcode › ListNode.java
leetcode/src/com/leetcode/ListNode.java at master · interviewcoder/leetcode
Leetcode solutions, code skeletons, and unit tests in Java (in progress) - leetcode/src/com/leetcode/ListNode.java at master · interviewcoder/leetcode
Author: interviewcoder
🌐
GitHub
github.com › ltongrc › leetcode › blob › master › ListNode.java
leetcode/ListNode.java at master · ltongrc/leetcode
public static ListNode testCase(){ int[] test = {44, 23, 12, 23, 0, 29, 12, 20}; ListNode head = new ListNode(test[0]); ListNode it = head; for(int i=1; i<test.length; i++){ it.next = new ListNode(test[i]); it = it.next; } return head; ·
Author: ltongrc
Find elsewhere
🌐
LeetCode The Hard Way
leetcodethehardway.com › basic topics › linked list
Linked List | LeetCode The Hard Way
class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode ptr = head; // find the size int size = findSize(head); ptr = head; // if size is equal to the n, remove node at head if (size == n) { ptr = ptr.next; head = ptr; return head; } // move ptr to the node just before the node to remove for (int i = 0; i< size - n - 1; i++) { ptr = ptr.next; } // check if the node to remove is the last node if (ptr.next.next != null){ ptr.next = ptr.next.next; } else { ptr.next=null; } return head; } // method to find the size of the list public int findSize(ListNode head) { // temporary pointer at head ListNode ptr = head; int size = 0; // increase the size till we reach the end of the list while (ptr != null) { size += 1; ptr = ptr.next; } return size; } }
🌐
LeetCode
leetcode.com › discuss › general-discussion › 1297479 › java-listnode-a-new-listnode-generates-0-and-not-null
[Java] ListNode a = new ListNode() -- generates [0] and not null - Discuss - LeetCode
June 25, 2021 - public ListNode mergeKLists(ListNode[] lists) { ListNode fin = new ListNode(); ListNode origHead = fin; if(lists.length == 0) return null; while(true) { int minIndex = -1; int minValue = Integer.MAX_VALUE; for(int i=0;i<lists.length;i++) { if(lists[i] != null && lists[i].val < minValue) { minIndex = i; minValue = lists[i].val; } } if(minValue == Integer.MAX_VALUE) return origHead; lists[minIndex] = lists[minIndex].next; fin.val = minValue; fin.next = new ListNode(); fin = fin.next; } }
🌐
LeetCode
leetcode.com › problems › add-two-numbers › solutions › 1264577 › python-solution-by-create-a-new-listnode
Python Solution (by Create a New ListNode) - Add Two ...
June 11, 2021 - Can you solve this real interview question? Add Two Numbers - You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit.
🌐
GitHub
github.com › mcclee › Leetcode-python-Listnode
GitHub - mcclee/Leetcode-python-Listnode: A python class to convert list to Listnode · GitHub
A python class to convert list to Listnode Usage: from ListToListnode import FuckListnode list1 = [1, 2, 3, 4] f = FuckListnode() listnode = f.returnNode(list1)
Author: mcclee
🌐
GitHub
github.com › doocs › leetcode › blob › main › solution › 0100-0199 › 0141.Linked List Cycle › README_EN.md
leetcode/solution/0100-0199/0141.Linked List Cycle/README_EN.md at main · doocs/leetcode
* class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { Set<ListNode> s = new HashSet<>(); for (; head != null; head = head.next) { if (!s.add(head)) { return true; } } return false; } }
Author: doocs
🌐
LeetCode
leetcode.com › discuss › study-guide › 1800120 › become-master-in-linked-list
Become Master In Linked List - Discuss - LeetCode
February 26, 2022 - class Solution { public ListNode middleNode(ListNode head) { // Base Condition if(head.next == null) return head; ListNode slow = head; ListNode fast = head; while(fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; } return slow; } }
🌐
LeetCode
leetcode.com › problems › reverse-linked-list › solutions › 172785 › Python-simple-code-by-using-ListNode-class-definition-(OOP-style).
Python simple code by using ListNode class definition ...
September 21, 2018 - Can you solve this real interview question? Reverse Linked List - Given the head of a singly linked list, reverse the list, and return the reversed list. Example 1: [https://assets.leetcode.com/uploads/2021/02/19/rev1ex1.jpg] Input: head = [1,2,3,4,5] Output: [5,4,3,2,1] Example 2: [https://assets.leetcode.com/uploads/2021/02/19/rev1ex2.jpg] Input: head = [1,2] Output: [2,1] Example 3: Input: head = [] Output: [] Constraints: * The number of nodes in the list is the range [0, 5000]. * -5000
🌐
GitHub
github.com › doocs › leetcode › blob › main › solution › 0800-0899 › 0876.Middle of the Linked List › README_EN.md
leetcode/solution/0800-0899/0876.Middle of the Linked List/README_EN.md at main · doocs/leetcode
* public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode middleNode(ListNode head) { ListNode slow = head, fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } }
Author: doocs
🌐
Medium
medium.com › @stevenbrunoqst › leetcode-data-structure-linked-list-a8cf8e1b8d8d
Leetcode — Data structure — Linked list | by Stevenbrunoqst | Medium
October 7, 2024 - # node class definition class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next # node instance initialization node = ListNode() # initialize a dummy node in front of the head node # and set cur pointer start from this dummy node dummy_node = ListNode(next=head_node) cur = dummy_node # 203 remove a node in linked list: as example for explaining the function of dummy node # and how to traverse a linked list class Solution: def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]: dummy_node = ListNode(next=head) temp = dummy_node # when th