簡體   English   中英

如果 item 為非數字或大於特定值,如何從列表列表中刪除列表?

[英]How do I remove list from list of lists if item is non-numeric or greater than a specific value?

我需要完成一項任務,其中涉及在 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']]

提前致謝 :)

問題是您在循環期間更改了列表,這會導致意外結果。 我建議不要刪除該元素 - 只需將其“標記”以進行刪除並在返回之前將其刪除。

這是這樣做的示例方法,無需修改您的大部分代碼:

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

這是使用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']])

您可以使用單線實現您想要的功能,如下所示:

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']]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM