FAQ: Linked Lists: Python - Linked Lists Implementation II

This community-built FAQ covers the “Linked Lists Implementation II” exercise from the lesson “Linked Lists: Python”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Computer Science

Linear Data Structures

FAQs on the exercise Linked Lists Implementation II

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Step 2 is confusing: You can use a while loop and Node 's next_node() method to traverse the list.

This is the solution version. How does the following work? I understand while loop using relation operators makes sense to me .

x=0
while x <3:
  print(x)
  x += 1

But I don’t understand the following:

 current_node = self.get_head_node()
    while current_node:
      if current_node.get_value() != None:
        string_list += str(current_node.get_value()) + "\n"
      current_node = current_node.get_next_node()

How does this while loop check a True or False? What is it doing in these terms, specifically for linked lists?

1 Like

Alright, so visualizing this and hopefully trying to answer my own question:

Nodes actually look like this ( # is a place holder for value, and I’ll use different brackets to help with visualization):

blah_name = Node [ # , {#, (#, None) } ]

The head node contains all the nodes in it’s 2nd argument. So when :

current_node = current_node.get_next_node()

gets the None value, does that equate to false, thus stopping the while loop? But the if statement is checking for the None. Can someone try to break it down for me what the while loop is doing in this scenario?

I think the next lesson gave me a clue!

Traverse the list until current_node.get_next_node().get_value() is the value_to_remove .

(Just like with stringify_list you can traverse the list using a while loop that checks whether current_node exists.)

It would still be nice to get a more detailed explanation of what while does through each check, especially at the end.

So this is what I’m working with currently:

 def stringify_list(self):
    node_v = []
    nxt = self.head_node.get_next_node()
    node_v.append(str(self.head_node.get_value()))
    
    while nxt != None:
      node_v.append(str(nxt.get_value()))
      nxt = nxt.get_next_node()
      
    node_v = [n + "\n" for n in node_v]  
    
    return node_v

but every way I’ve tried, I can’t get the the list items to print on separate lines. I keep getting

['90\n', '5675\n', '70\n', '5\n']

I also get the following message at the bottom of the workspace:

'list' object has no attribute 'split'

I get this message wit or without an attempt to print on separate lines.
Any advice?

1 Like

This exercise was a struggle for me, partially because the instructions are a bit too abstract and unclear. First, although the directions only say to uncomment the print statement at the end, you actually have to uncomment ALL the statements for it to run correctly.

As for the code itself, it helped me to write out the process for stringify_list() in pseudocode first:

def stringify_list(self):
  # create empty string to hold values
  string = ""

  # keep track of the current node, starting with the head node
  current_node = self.get_head_node()

  # while we're not at the end of the linked list:
  while current_node:

    # get the value of the current node
    # convert that value to a string
    # add it to the string variable created in the beginning (with a new line)
    string += str(current_node.get_value()) + "\n"

    # move to the next node
    current_node = current_node.next_node

  # once we reach the end of the linked list, return the full string
  return string
1 Like

Nitpick, maybe, but isn’t it customary Python procedure to name as __str__() the method we have coded and named stringify()? That way, it can be invoked by simply calling list_name.print().

I struggled with the second to last step a lot with this one. Is there any way I could condense this code? I feel like I’m adding a lot of extra steps into it for no reason but I’m struggling to figure out how to make it better.

def stringify_list(self):
string_list =
current_node = self.head_node
while current_node:
if current_node.get_value != None:
string_list.append(str(current_node.get_value()))
current_node = current_node.get_next_node()
stringified = ‘\n’.join(string_list)
return stringifiedPreformatted text

You could make it a string in the first place. There is no need to go through a ‘list’ phase. The append() line could just be a += line.

while current_node: does the same thing as if current_node.get_value != None: but with loop.
So might as well delete the second conditional statement.

1 Like

I am struggling to find what is “while current_node:” in the below code doing.
Can anyone explain it.

def stringify_list(self):
    string_list = ""
    current_node = self.get_head_node()
    while current_node:
      if current_node.get_value() != None:
        string_list += str(current_node.get_value()) + "\n"
      current_node = current_node.get_next_node()
    return string_list

It would appear the if statement is redundant since the while condition will fail if the current_node value is None.

However that is ambiguous because it will also be falsy if 0, '', "", or the boolean, False. What if those are valid node values?

string_list = “”
current_node = self.get_head_node()
#get the head_node as the current node

while current_node:
  if current_node.get_value() != None:
    string_list += str(current_node.get_value()) + "\n"

#append the value of the nodes aleady put in the list (traverse) and transfer them into strings.

  current_node = current_node.get_next_node()

This code here is in the while loop, but cannot be placed on the top of if loop. When getting the next node, there is no value in the next node because you don’t use get_value function, so the value will be “None”. Then the console will show an error because “AttributeError: ‘NoneType’ object has no attribute ‘get_value’”.
Therefore, the logic here is to check the value in the current node and then repeatedly check the next node. And check the value in the nodes. Then print out.

This code can be put into the end of the if loop The logic is the same when in the if loop or the while loop.

My understanding of the while statement is that it takes a boolean object, i.e. an object with a truth value of True or False. If the object’s truth value is True, then the loop body is executed. If it is False, then the loop body is not executed.

In this example, it seems to me that the current_node object in the while current_node: line is trivially true. According to the Python documentation, every object has a default truth value of True, apart from a few exceptions (e.g. None, False, 0). Since the truth value of current_node is True, the ensuing loop body is executed. The current_node object functions as a placeholder for the ensuing if statement to do the heavy lifting, if you will.

This helps to explain why there is some confusion about the while current_node: line. The course has not introduced a usage context for the while statement in which the boolean object it takes has a trivial truth value.

Do you agree that this is the case?

…and as I was pondering this issue I reached a further insight that others in this forum have alluded to.

Eventually, the while statement will have iterated through all of the nodes, and therefore current_node.get_next_node() will return None. Since current_node is set to be equal to current_node.get_next_node(), eventually the value of current_node will be set to None. When this happens, the while statement takes the object None in its next iteration, closing the loop, since the truth value of None is False.

1 Like

One of the exceptions to " every object has a default truth value of True" is

  • empty sequences and collections: '' , () , [] , {} , set() , range(0)

Since a node is a dictionary, if current_node is empty, it will have a truth value of False. So the truth value of current_node is hardly trivial.

1 Like

Thanks for posting. That’s exactly what I realized by the second time I posted. Plus the notion of a node as a dictionary, which I hadn’t thought about, is interesting.

Precisely. This case is a more straightforward than I implied above. In the Graphs & Maps lessons, nodes are indeed dictionaries. But, in the linked Lists lessons, nodes are actually instances of a class, Node. The docs tell us that objects (such as class instances) can have a truth value of False if

its class defines either a __bool__() method that returns False or a __len__() method that returns zero, when called with the object.

… neither of which, the Node class has. But, as you point out, the code actually assigns the variable current_node the value None, effectively flipping the “while” switch.

1 Like