Python列表移除含指定字符串元素失败:原因及解决方法
问题描述
给定列表:
myList = ['CLIPPOLY', 'ExternalCrosswalk','CrossReference', 'SourceCitation', 'Status', 'Waterbody', 'N_1_EDesc', 'N_1_ETopo', 'N_1_JDesc', 'N_1_JTopo', 'N_1_Props', 'Line']
尝试移除所有包含'N_1'的元素,使用如下代码:
for item in myList: if 'N_1' in item: myList.remove(item) print("Removed item: {}".format(item))
输出仅移除了3个元素:
Removed item: N_1_EDesc Removed item: N_1_JDesc Removed item: N_1_Props
打印myList发现仍有'N_1_ETopo'、'N_1_JTopo'未被移除:
print(myList)
返回:
['CLIPPOLY','ExternalCrosswalk','CrossReference','SourceCitation','Status','Waterbody','N_1_ETopo', 'N_1_JTopo','Line']
使用待移除列表bad_list判断后移除,结果同样存在问题。
问题原因
在遍历列表的同时直接修改原列表(移除元素)会打乱遍历的索引逻辑:
- Python的
for循环遍历列表时,是按索引顺序依次访问元素的。 - 当你移除当前索引的元素后,列表中该位置之后的所有元素都会向前移动一位,填补被移除元素的位置。
- 下一次循环会直接访问下一个索引,导致跳过了原本位于被移除元素之后、现在前移到当前索引的元素。
举个具体例子:
- 遍历到索引6的
N_1_EDesc并移除它,此时原索引7的N_1_ETopo移动到索引6。 - 下一次循环直接访问索引7,此时索引7的元素已经变成了原索引8的
N_1_JDesc,直接跳过了现在在索引6的N_1_ETopo。
解决方法
方法1:遍历列表的副本
遍历原列表的拷贝,这样修改原列表不会影响遍历的过程:
myList = ['CLIPPOLY', 'ExternalCrosswalk','CrossReference', 'SourceCitation', 'Status', 'Waterbody', 'N_1_EDesc', 'N_1_ETopo', 'N_1_JDesc', 'N_1_JTopo', 'N_1_Props', 'Line'] for item in myList.copy(): if 'N_1' in item: myList.remove(item) print("Removed item: {}".format(item)) print(myList)
方法2:使用列表推导式(推荐)
这是Python中最简洁高效的方式,直接生成过滤后的新列表:
myList = ['CLIPPOLY', 'ExternalCrosswalk','CrossReference', 'SourceCitation', 'Status', 'Waterbody', 'N_1_EDesc', 'N_1_ETopo', 'N_1_JDesc', 'N_1_JTopo', 'N_1_Props', 'Line'] myList = [item for item in myList if 'N_1' not in item] print(myList)
如果用bad_list判断:
bad_list = ['N_1_EDesc', 'N_1_ETopo', 'N_1_JDesc', 'N_1_JTopo', 'N_1_Props'] myList = [item for item in myList if item not in bad_list]
方法3:反向遍历列表
从列表末尾往前遍历,这样移除元素不会影响前面未遍历的元素索引:
myList = ['CLIPPOLY', 'ExternalCrosswalk','CrossReference', 'SourceCitation', 'Status', 'Waterbody', 'N_1_EDesc', 'N_1_ETopo', 'N_1_JDesc', 'N_1_JTopo', 'N_1_Props', 'Line'] for item in reversed(myList): if 'N_1' in item: myList.remove(item) print("Removed item: {}".format(item)) print(myList)
内容的提问来源于stack exchange,提问作者gwydion93
相关产品推荐
相关产品推荐

