python中的for循环不操作原始对象,而是执行深拷贝

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

我正在对 Python 中的列表执行 for 循环,据我所知应该为列表中的每个元素创建一个浅表副本。但是,当我对元素执行操作时,更改并没有反映在原始列表中。

代码如下:

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

    print(interactions)

给定初始列表 ['. Bph\n', 'Cardiovascular\n', 'Diabetes\n', '. '] 的此操作的输出是:

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

尽管当我跟随调试器时,我可以看到在 interaction 上执行了正确的操作,但这些更改并没有反映在交互中。我在这里做错了什么?

为什么要反映?您正在修改 str 元素,但它们无法就地更改,返回包含更改值的新字符串;原始列表中没有任何反映。 :-)

相反,您应该遍历 interactions[:] 的副本并使用索引 enumerate 进行分配产生:

for i, interaction in enumerate(interactions[:]):
    # redundant in this snippet
    orig = interaction   
    # strip() will remove '\n' and leading-trailing ' '
    interaction = interaction.replace('.', '').replace(' ', '').strip('\n')   
    # if interaction: suffices
    if len(interaction) == 0:  
        interactions.remove(orig)
    else:
        interactions[i] = interaction
    print(interactions)

现在输出为:

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

Python 字符串是不可变的,因此您要么需要用清理后的版本替换每个元素(使用 Jim 的回答中的索引),要么构建一个新列表。 IMO 最巧妙的方法是使用列表理解:

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