<p>问题是在循环过程中更改列表会导致意外的结果。我建议不要删除这个元素-只要“标记它”删除,并在返回之前删除它</p>
<p>这是这样做的一个示例,无需修改大部分代码:</p>
<pre><code>datalist = [['16', '10', '8', '3', '7'], ['8', '9', '19', '20', '4'], ['6', '8', '16', '5', '0'], ['1', '30', '2', '5', '7'], ['14', '1', '2', '9', '3'], ['6', '9', '16', '0', ''], ['14', '11', 'forteen', '8', '20'], ['12', '11', '8', '15', '7'], ['18', '9', '9', '22', '4'], ['1', '3', '14', '18', '20'], ['5', '3', '19', '20', '0'], ['einundzwanzig', '14', '1', '2', '4']]
invalidList = []
def validate(myList): #non-numeric values or values greater than 20 must be removed from myList and added to invalidList
for lst in myList: # check each list
for item in lst:# check element in each list
try:
val = int(item)
if val >20:
raise ValueError
except ValueError:
invalidList.append(lst[:]) # copy the invalid list - otherwise the next line would break it because they share the list object
lst.clear() # this will change the invalid list
return [elem for elem in myList if elem] # empty list evaluate to False
</code></pre>
<p>返回值:</p>
<pre><code>>>> validate(datalist)
[['16', '10', '8', '3', '7'], ['8', '9', '19', '20', '4'], ['6', '8', '16', '5', '0'], ['14', '1', '2', '9', '3'], ['12', '11', '8', '15', '7'], ['1', '3', '14', '18', '20'], ['5', '3', '19', '20', '0']]
>>> invalidList
[['1', '30', '2', '5', '7'], ['6', '9', '16', '0', ''], ['14', '11', 'forteen', '8', '20'], ['18', '9', '9', '22', '4'], ['einundzwanzig', '14', '1', '2', '4']]
</code></pre>
<hr/>
<h3>为什么会这样?</h3>
<p>当您从列表中间移除一个项目时,所有其他元素都会向左移动</p>
<p>这意味着,移除一个元素后,下一个元素跳转到被移除的元素所在的位置。。。但是循环继续,到下一个地方</p>
<p>当您的列表在行中包含两个无效元素时,第二个元素总是被跳过,因为它跳转到该位置,如下所示:</p>
<pre><code>[['16', '10', '8', '3', '7'], #ok
['8', '9', '19', '20', '4'], #ok
['6', '8', '16', '5', '0'], #ok
['1', '30', '2', '5', '7'], #removed
['14', '1', '2', '9', '3'], #skipped! but ok
['6', '9', '16', '0', ''], #removed
['14', '11', 'forteen', '8', '20'], #skipped! but should've been removed
['12', '11', '8', '15', '7'], #ok
['18', '9', '9', '22', '4'], #removed
['1', '3', '14', '18', '20'], #skipped! but ok
['5', '3', '19', '20', '0'], #ok
['einundzwanzig', '14', '1', '2', '4']] #removed
</code></pre>