Python Python Collections Lists Removing items from a list

This worked for this challenge, but is their an easier way that I'm not seeing.

I also used the .removed for the last 3 lines of code and it worked as well, but is there a way to combine some of these? Thanks in advance!

lists.py
messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
value_1 = messy_list.pop(3)
messy_list.insert(0, value_1)
del messy_list[1]
del messy_list[3]
del messy_list[3]

2 Answers

Alex Koumparos
MOD
Alex Koumparos
Python Web Development Treehouse Moderator 32,442 Points

Hi Angela,

Great question! It's relatively easy to shorten the task of adding the popped value back into the list: instead of assigning the result of the pop expression to a variable and then inserting that variable, you can perform the pop expression inside the call to the insert method:

messy_list.insert(0, messy_list.pop(3))

Finding a way to simplify the del/removes is more difficult though. With just three items to work on and no broader context to understand how we might reuse this code, it's probably best to just do the three separate operations.

However, if we were in a situation where we had to remove many more items from a correspondingly larger list, it would be worth taking the time to write some code that would iterate through the list removing items, but we're still looking at several lines if we use a for loop or one quite long line if we want to use a list comprehension.

The for loop version would look something like this:

items_to_remove = ["a", False, [1, 2, 3]]
new_list = []
for item in messy_list:
    if item not in items_to_remove:
        new_list.append(item)

Note that we are building up a new list from the items to keep, rather than removing the items we want to get rid of, this is because we don't want to iterate through a list we are removing items from (it can cause Python to skip over items).

Obviously you'd want to be removing more than three items before it made sense to replace your code with this (and you could have your items_to_remove list programmatically generated instead of hard-coded).

You might not be familiar with list comprehensions yet, so the following might look weird. If so, it's a way of building a list from an expression described with a for loop and (optionally) a conditional. They are a compact way of representing the kind of for loop we wrote above.

items_to_remove = ["a", False, [1, 2, 3]]
new_list = [ item for item in messy_list if item not in items_to_remove ]

Hope that clears things up.

Happy coding,

Alex

Wow! You put a lot of thought and time into your response. Thanks very much. I doing the data and algorithms class on Treehouse and I think (from what I understand), I'm supposed to be finding the most efficient way to solve a problem. I appreciate it, Alex. Thanks very much! :)

Alex Koumparos
MOD
Alex Koumparos
Python Web Development Treehouse Moderator 32,442 Points

Hi Angela,

You're spot on that different approaches to solving the problem can have wildly different performance considerations and so some solutions will often be significantly more or less efficient than others.

I don't think Python has a built-in algorithm to simplify the above code (if it did, that would probably be the most efficient) and I would expect both of the approaches I described above to have similar performance characteristics to each other as a list comprehension is basically just a 'for in' loop hidden inside a list. We can sort of intuit whether our approach is at least in the right "O" category of performance by thinking about what the minimum number of things we'd have to do to solve the problem manually would be, and then seeing how many times our algorithm has to do whatever it is doing.

In the case of this problem, any approach is going to need to look at every item in the array once, to decide whether that particular item is going to need to be removed, and thus we can't expect to have an algorithm that removes multiple items to be better than linear time (O(n)). Since a for-loop is a linear loop through the problem space, we know that using a single for-loop is going to give us a linear time algorithm.

Within linear time algorithms there is definitely room to test whether certain approaches can shave a bit of processing time off a problem. Because it can be a complex and unpredictable path from your Python script to compiled C code to machine code, some approaches that might seem faster will end up being slower and vice versa (at least within a same order of complexity).

Most code doesn't end up being a performance bottleneck, but all code can be a potential source of bugs, and we read code more often than we write it, Therefore, once you have an algorithm that is in the right order of complexity, it's often best to focus on writing the code in the way that is most readable rather than try to eke out the very best performance on day 1.

Cheers!

Alex