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
我正在对 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