在Python中提取和替換滿足字符串列表(數組)條件的元素

商業

要從元素為字符串的列表(數組)生成新列表,通過僅提取滿足特定條件的字符串元素,或執行替換、轉換等,使用列表推導。

在簡單解釋了列表推導之後,下面的內容用示例代碼來解釋。

  • 根據是否包含特定字符串進行提取(部分匹配)
  • 替換特定字符串
  • 以特定字符串開頭或不開頭進行提取
  • 以特定字符串結尾或不結尾提取
  • 案例判斷提取
  • 轉換大寫和小寫
  • 確定是使用字母還是數字字符並提取它們
  • 多個條件
  • (計算機)正則表達式

請注意,列表可以存儲不同類型的數據,並且與數組完全不同。如果要在需要內存大小和內存地址的進程中處理數組或對大數據進行數值處理,請使用數組(標準庫)或 NumPy。

列表包含符號

從列表生成新列表時,列表推導式比 for 循環更容易編寫。

[expression for any variable name in iterable object if conditional expression]

如果元素只是被條件表達式選擇,它不會被表達式處理,所以它採用以下形式

[variable name for variable name in original list if conditional expression]

如果將if條件表達式做成if not條件表達式,則變為否定,可以提取不滿足條件表達式的元素。

包含特定字符串(部分匹配) \ 不包含:in

在“原始字符串中的特定字符串”中,如果原始字符串包含特定字符串,則返回 True。這是一個條件表達式。

in 的否定是用 not in 完成的。

l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']

l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']

l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']

替換特定字符串

如果要替換列表元素的字符串,請對列表理解表示法中的每個元素使用字符串方法 replace()。

如果沒有要替換的字符串,則不需要在 if 條件表達式中選擇元素,因為它不會通過應用 replace() 來更改。

l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']

如果要替換包含特定字符串的整個元素,請使用 in 提取它並使用三元運算符對其進行處理。三元運算符的寫法如下。
True Value if Conditional Expression else False Value

如果列表理解符號的表達式部分是三元運算符,則可以。

l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']

以下是結果的摘要,括在括號中。如果您不習慣使用括號,可能會更容易理解並避免錯誤。從語法上講,即使你寫括號也沒有問題。

[('ZZZ' if ('XXX' in s) else s) for s in l]

使用 in 作為條件會與列表理解符號 in 混淆,但如果您了解列表理解符號和三元運算符的語法形式,這並不難。

以特定字符串開頭 \ 不開始:startswith()

如果字符串以參數中指定的字符串開頭,則 string 方法 startswith() 返回 true。

l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']

l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']

以特定字符串結尾 \ 不結束:endswith()

如果字符串以參數中指定的字符串結尾,則字符串方法 endswith() 返回 true。

l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']

l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']

案例判斷提取

字符串方法 isupper(),islower() 可用於確定字符串是全大寫還是全小寫。

l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']

轉換大寫和小寫

如果要將所有字符轉換為大寫或小寫,請使用字符串方法 upper() 和 lower()。其他方法包括 capitalize(),它只將第一個字母大寫,以及 swapcase(),它交換大小寫字母。

與上面的替換示例一樣,如果您只想處理滿足條件的元素,請使用三元運算符。

l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']

l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']

確定是使用字母還是數字字符並提取它們

字符串方法 isalpha() 和 isnumeric() 可用於確定字符串是否全是字母、數字等。

l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']

l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']

多個條件

列表推導的條件表達式部分可以是多個條件。也可以使用否定的“非”條件。

當使用三個或更多條件表達式時,將每個組括在括號 () 中會更安全,因為結果會因順序而異。

l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']

l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']

(計算機)正則表達式

正則表達式允許高度靈活的處理。

re.match() 在匹配時返回的匹配對像在使用條件表達式求值時始終確定為真。如果不匹配,則返回 None,在條件表達式中為 false。因此,如果您只想提取與正則表達式匹配的元素,只需像以前一樣將 re.match() 應用於列表推導表達式的條件表達式部分。

import re

l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']

l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']

re.sub() 替換正則表達式的匹配部分,也很有用。要僅提取和替換匹配的元素,只需添加“if 條件表達式”。

l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']

l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']