Python中while循环内data['text'][i]类型修改失效问题咨询
问题分析与修复方案
哎,这个问题其实是循环索引的顺序踩坑了,咱们一步步捋清楚:
为什么第一个循环的修改在内循环不生效?
你看你的代码逻辑:
i = 0 while i < len(data['text']): data['text'][i] = data['text'][i].split() # 把第i个元素转成列表 j = 0 i += 1 # 这里直接把i加1了! while j < len(data['text'][i]): # 现在i已经是下一个元素的索引了! # ... 处理操作
问题就在这里:你刚把data['text'][i]转成列表,立刻就把i加1了,紧接着内循环处理的是data['text'][i]——也就是下一个还没被split转换的原始字符串!所以内循环里调用remove()的时候,自然会报错“字符串没有remove属性”,因为你操作的根本不是刚才转好的列表元素。
为什么二次转换会在j==2时报错?
如果你在内循环里再加一次split,第一次j=0的时候,会把当前的字符串转成列表;但当j走到2的时候,这个元素已经是列表了,再调用split()就会触发'list' object has no attribute 'split'的错误,这很合理——列表哪来的split方法嘛。
修复后的代码
调整一下i +=1的位置,把它放到内循环结束之后,这样内循环处理的就是刚刚转好的列表元素:
i = 0 while i < len(data['text']): # 先把当前元素转成列表 data['text'][i] = data['text'][i].split() j = 0 # 处理当前i对应的列表元素 while j < len(data['text'][i]): if data['text'][i][j].startswith('@'): data['text'][i].remove(data['text'][i][j]) j -= 1 # 删除元素后,后面的元素前移,必须减1避免跳过元素 else: # 注意:strip是返回新字符串,必须重新赋值才会生效 data['text'][i][j] = data['text'][i][j].strip('#') j += 1 # 处理完当前元素,再移动到下一个 i += 1
另外还要提醒你两个细节:
- 字符串是不可变类型,
strip('#')不会修改原字符串,必须把返回值重新赋值给原位置,否则你的去#操作等于白做; - 删除列表元素后,一定要把j减1,因为删除元素后列表长度变短,后面的元素会往前挪一位,不减1的话会跳过下一个元素。
内容的提问来源于stack exchange,提问作者Trinidad
相关产品推荐
相关产品推荐

