I am a beginner in Python and programming in general and currently training with kata on codewars. I sometimes still struggle with syntax and logic of course but I cannot seem to figure out why my solution is not working for the following exercise and need someone to explain to me where my logic is wrong and why.
"Take an array and remove every second element from the array. Always keep the first element and start removing with the next element.
Example:["Keep", "Remove", "Keep", "Remove", "Keep", …] –> ["Keep", "Keep", "Keep", …]
None of the arrays will be empty, so you don’t have to worry about that!"
So I figured that the element to be removed must have an odd index and tried to solve this problem using a for-loop and modulo:
When I run the code with the following lists:
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
my_list2 = ["hello", "goodbye", "hello again"]
my_list3 = [[1, 2], [1, 2]]
my_list4 = [["goodbye"], {"Great": "Job"}, ["Goodbye"]]
These are the results when I run my code and print the lists afterwards:
['hello', 'hello again']
[1, 3, 4, 6, 7, 9, 10]
[[1, 2], [1, 2]]
[['goodbye'], ['Goodbye']]
It seems odd to me that the code works for a list of strings (my_list2) as well as for a list of lists but (my_list4) but not if the list of lists contains integers instead of strings inside the inner lists (my_list3) or if it is a list containing integers instead of strings (my_list).
Does Python treat lists differently depending on their contents? I feel like that should not matter here since I am checking the indexes of the elements and not the values itself. So what am I missing?
>Solution :
Consider the side effects of mutating the list you are iterating over.
For the example of my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
When you reach your first odd index, you are altering the exact list you continue to iterate over. Your new list looks like this:
[1, 3, 4, 5, 6, 7, 8, 9, 10]
You’ve changed the size! This means all the indexes are different, and the for loop continues onto the following index. This is hard to reason about.
Often, it’s conceptually simpler and less error-prone to build a new list with the values you want. Maybe something like:
def remove_every_other(my_list):
new_list = []
# enumerate is a pythonic alternative for doing your my_list.index(element) idea
for idx, element in enumerate(my_list):
if idx % 2 == 0:
new_list.append(element)
return new_list