Logic of .remove() on a 2d list

Task 6 of https://www.codecademy.com/courses/learn-python-3/lessons/create-python-list/exercises/review prompts me to use .remove() to delete a value in a 2d list.

I first tried customer_data.remove([1][2]) which was incorrect. I eventually found out the correct syntax is customer_data[1].remove(customer_data[1][2]),
Could someone help me understand this logic please?

I understand that this is a long post, so if you need the fast rundown check the TL;DR at the bottom. However if you have time, the longer part is worth it.


What is the remove method?

What the remove() method does from the documentation is take the value in the list to be removed as an argument. So if you have a list [1, 2, 3, 4, 5] and you wanted to remove 3, you would do [1, 2, 3, 4, 5].remove(3).

Code Analysis

So lets take your code first. You said you tried customer_data.remove([1][2]) which didn’t work. Lets think about what this is doing if you work from left to right.

  1. Select the customer_data list, which in this instance is a 2-dimensional list.
  2. Flag that an element is to be removed, the argument passed is [1][2].
  3. Interpret [1][2]. As there is nothing in front of it, [1] is taken as a list with a single element. It then uses [2] and tries to get the element with index 2. However this does not exist so it flags an index error.

So we see it doesn’t even make it to interpreting the 2-D list, as it is stopped by the error inside the brackets. Okay so we realise that [1] is being interpreted as a list and that we don’t want, it should be an index of customer_data. So now we have:

customer_data.remove(customer_data[1][2])

Run that and we get another error. Specifically “ValueError: list.remove(x): x not in list”. So the problem is still that x isn’t in the list, why is that? Lets walk through it again.

  1. Select the customer_data list, which in this instance is a 2-dimensional list.
  2. Flag that an element is to be removed, the argument passed is customer_data[1][2]. This evaluates to the 3rd element of the 2nd list, which is False. So now we have customer_data.remove(False).
  3. Check customer_data for the element “False”. This flags the error.

So why does this flag the error? Well all of the elements of customer_data are arrays, and it’s searching for a single boolean. However, we want to check a specific array nested in customer_data, the one with Ben’s data. This is the element with index 1 in customer_data, so we end up with the working code:

customer_data[1].remove(customer_data[1][2])

TL;DR


The summary of this is that the remove method takes in the actual value of the element to me removed and not the indexes. Therefore your initial error is because [1][2] in isolation just tells python you want the 3rd element of the list [1]. And as in the first sentence, the reason we use customer_data[1][2] is because we don’t want the path to the element, we want the value itself.

The next error was simply because you hadn’t selected the right list to remove from! Instead of accessing just the 2D list, you needed to access the correct sublist first so python knew where to remove from. That’s how you end up with the working code you found above.


Hopefully that explanation was helpful, and for any other questions just ask!

2 Likes

Thank you for the thorough response. It has helped me to understand it better. If I understand correctly, customer_data[1] targets Ben’s customer data sublist and .remove(customer_data[1][2]) removes the False value.

My next question is why does Ben’s list have to be referenced twice?

customer_data[1] tells python I want his customer data so why do I have to pass the redundant[1] in .remove(customer_data[1][2])as part of the argument?

This is just a consequence of how the remove() method works. The value to be removed needs to be passed, and so you can do this in multiple ways:

customer_data[1].remove(customer_data[1][2])

customer_data[1].remove(False)

customer_data[1].remove(not True)

customer_data[1].remove(customer_data[3][2])

all of the above are equivalent in this scenario, as the remove method doesn’t assume you are referencing the array you want to remove from. It just needs the value that should be removed. Therefore we need to give the full path to the value in the array otherwise you’ll get errors flagging up.
That is all to say, python, and specifically the remove method has no idea that the value you want to pass is part of customer_data[1]. If it assumes as such then in this specific scenario it is easier, but in most use cases for the remove method it would make life much harder.

1 Like