我需要完成一项任务,其中涉及清理Python中的列表列表。如果子列表包含非数字或数字但大于20的项目,则需要删除该子列表并将其添加到单独的列表中。
我当前的代码正确地删除了一些子列表,但没有删除其他子列表。我认为这是因为两个连续的子列表出现错误,但我无法解决此问题。我的代码:
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)
myList.remove(lst)
return myList
有问题的子列表是:
['14', '11', 'forteen', '8', '20']
实际输出:
>>> print(validate(datalist)) # this should be the cleansed list
[['16', '10', '8', '3', '7'], ['8', '9', '19', '20', '4'], ['6', '8', '16', '5', '0'], ['14', '1', '2', '9', '3'], ['14', '11', 'forteen', '8', '20'], ['12', '11', '8', '15', '7'], ['1', '3', '14', '18', '20'], ['5', '3', '19', '20', '0']]
>>> print(invalidList)
[['1', '30', '2', '5', '7'], ['6', '9', '16', '0', ''], ['18', '9', '9', '22', '4'], ['einundzwanzig', '14', '1', '2', '4']]
预期输出:
>>> print(validate(datalist)) # this should be the cleansed list
[['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']]
>>> print(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']]
预先感谢:)
答案 0 :(得分:1)
问题是您在循环期间更改了列表,这导致了意外的结果。我建议不要删除该元素-只需将其“标记”为删除,然后在返回之前将其删除。
这是一个示例方法,无需修改很多代码:
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
返回值:
>>> 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']]
从列表中间删除一项时,所有其他元素向左移动。
这意味着,在删除一个元素之后,下一个元素会跳到被删除的位置...但是循环继续进行到下一个位置。
当列表中连续包含两个无效元素时,第二个元素总是会被跳过,因为它会跳到该位置,如下所示:
[['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
答案 1 :(得分:0)
这是使用any()
的一种方法。
例如:
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']]
def validate(myList):
invalidList = []
validList = []
for i in myList:
if any(j=='' or j.isalpha() or int(j) > 20 for j in i):
invalidList.append(i)
else:
validList.append(i)
return validList, invalidList
print(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']],
[['1', '30', '2', '5', '7'],
['6', '9', '16', '0', ''],
['14', '11', 'forteen', '8', '20'],
['18', '9', '9', '22', '4'],
['einundzwanzig', '14', '1', '2', '4']])
答案 2 :(得分:0)
您可以通过单线实现以下目标:
validlist = [sublist for sublist in datalist if all(i.isdigit() for i in sublist) and max([int(i) for i in sublist])<=20]
输出:
[['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']]