簡體   English   中英

如果條件在Python中為真,則從現有列表創建列表

[英]Creating a list from an existing list if a condition is true in Python

我正在嘗試從列表中刪除一些項目,

list1 = ["CCC-C", "CCC-P", "CCC-A-P", "CCC-A-H", "CCC-J", "CCC-S-X"]
new_list = [i for i in list1 if (len(i) == 5 or len(i) == 7 or i[6] != "H")]

除非list1任何項目的長度為5或7,或者其第7個字符為“ H”,否則它不應位於new_list

但是上面的代碼在new_list包含“ CCC-AH”項。 此外,在i [6]中檢查項目“ CCC-C”時,不會出現“ IndexError:字符串索引超出范圍”錯誤。 有任何想法嗎?

問候,

Python中的布爾表達式按以下順序執行:

>>> A() or B()

如果A()返回True,則無需檢查B()

>>> A() and B()

如果A()返回False,則無需檢查B()

我希望它能給您一些想法。

做這個:

new_list = [i for i in list1 if len(i)==5 or (len(i)==7 and i[6]!="H")]

這樣,除非最后一個字符是H (條件(len(i)==7 and i[6]!="H") ,否則您只會得到長度為5(條件len(i)==5 )或長度為7的項目。 (len(i)==7 and i[6]!="H") )。

僅當字符串的長度為7時,才會評估可能發生IndexError條件i[6]!="H" ,以確保您不會遇到此錯誤。

此外,在i [6]中檢查項目“ CCC-C”時,不會出現“ IndexError:字符串索引超出范圍”錯誤。

or短路。 如果為or或條件指定的第一個條件為True ,則不計算第二個條件,無論第二個參數的真值如何,總評估值仍為True

另外,“ CCC-AH”之所以匹配,是因為它的長度是7。如果您不希望那些以H結尾在第7位的字符串,無論它們的長度如何,都應重做邏輯表達式:

new_list = [i for i in list1 if (len(i) == 5 or len(i) == 7) and (i[6] != "H")]

正如其他人指出的那樣, len("CCC-AH") == 7並且python對布爾運算采用短路評估。 最終結果是:

(len("CCC-A-H") == 5 or len("CCC-A-H") == 7 or "CCC-A-H"[6] != "H")

將返回true,因為len("CCC-AH") == 7評估"CCC-AH"[6] != "H"之前len("CCC-AH") == 7 true,因此len("CCC-AH") == 7 "CCC-AH"[6] != "H"

通過使用filter(...)函數而不是列表推導,這可能更容易看到:

list1 = ["CCC-C", "CCC-P", "CCC-A-P", "CCC-A-H", "CCC-J", "CCC-S-X"]
def len57notHWrong(item):
    return len(item) == 5 or len(item) == 7 or item[6] != "H"

print "Wrong           : ", filter(len57notHWrong, list1)

這是您過去使用filter(...)函數的列表理解的簡單直接轉換。

如果我們使用if ... elif ... else構造重寫它,它將看起來像這樣:

def len57notHWrongExpanded(item):
    if len(item) == 5:     # first check if length is 5
        return True
    elif len(item) == 7:   # now check if length is 7
        return True        # it's 7? Short-circuit, return True
    elif item[6] != "H": # This will never get seen (on this particular dataset)
        return True

    return False

print "Wrong (Expanded): ", filter(len57notHWrongExpanded, list1)

正確的表達式如下所示:

def len57notH(item):
    return len(item) == 5 or (len(item) == 7 and item[6] != "H")

print "Correct         : ", filter(len57notH, list1)

擴展:

def len57notHExpanded(item):
    if len(item) == 5:
        return True
    elif len(item) == 7:
        if item[6] != "H":
            return True
    return False

print "Correct (Expand): ", filter(len57notHExpanded, list1)

這將使列表理解如下所示:

new_list = [i for i in list1 if (len(i) == 5 or (len(i) == 7 and i[6] != "H"))]

您的代碼沒有引發IndexError的原因是因為所有數據項的長度均為5或7個元素。 這將導致代碼在命中i[6] != "H"表達式之前短路。 如果在包含長度不為5或7且長度小於7個元素的數據項的列表上嘗試此代碼,則會引發IndexError:

list2 = ["CCC-C", "CCC-P", "CCC", "CCC-A-P", "CCC-A-H", "CCC-J", "CCC-S-X"]
new_list = [i for i in list2 if (len(i) == 5 or len(i) == 7 or i[6] != "H")]

Traceback (most recent call last):
  File "C:/Users/xxxxxxxx/Desktop/t.py", line 44, in <module>
    new_list = [i for i in list2 if (len(i) == 5 or len(i) == 7 or i[6] != "H")]
IndexError: string index out of range

抱歉,答案很長...

暫無
暫無

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

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