bendl bendl - 26 days ago 8
Python Question

For loop in python doesn't manipulate original objects, instead performs deep copy

I'm doing a for loop over a list in Python, which to all of my knowledge should create a shallow copy of each element in the list. However, when I perform operations on elements, the changes aren't being reflected in the original list.

Here's the code:

interactions = f.readlines()
for interaction in interactions:
orig = interaction
interaction = interaction.replace('.', '').replace(' ', '').strip('\n')
if len(interaction) == 0:
interactions.remove(orig)

print(interactions)


The output of this operation given an initial list of
['. Bph\n', 'Cardiovascular\n', 'Diabetes\n', '. ']
is:

['. Bph\n', 'Cardiovascular\n', 'Diabetes\n', '. ']
['. Bph\n', 'Cardiovascular\n', 'Diabetes\n', '. ']
['. Bph\n', 'Cardiovascular\n', 'Diabetes\n', '. ']
['. Bph\n', 'Cardiovascular\n', 'Diabetes\n']


Even though when I follow the debugger I can see the correct operations being performed on
interaction
but the changes just arent being reflected in interactions. What am I doing wrong here?

Answer

Python strings are immutable, so you either need to replace each element with your cleaned version (using indices like in Jim's answer) or build up a new list. IMO the neatest way to do this is with a list comprehension:

interactions = [i.replace('.', '').replace(' ', '').strip('\n') for i in interactions]
interactions = list(filter(None, interactions)) # Remove empty elements