Search code examples
pythonpython-3.xfor-loopshallow-copy

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?


Solution

  • 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