要从一个元素为字符串的列表(数组)中生成一个新的列表,只提取满足某些条件的字符串元素,或者进行替换、转换等,可以使用列表理解法。
在对列表理解进行了简单的解释之后,下面的内容将用示例代码进行解释。
- 根据是否包含特定字符串进行提取(部分匹配)。
- 替换特定的字符串
- 通过从或不从一个特定的字符串开始提取
- 通过以特定字符串结尾或不结尾来提取
- 判断和提取的案例
- 转换大写字母和小写字母
- 确定是否使用字母或数字字符并提取它们
- 多重条件
- (正则表达式
注意,列表可以存储不同类型的数据,与数组有严格的区别。如果你想在需要内存大小和内存地址的过程中处理数组,或者对大数据进行数值处理,请使用array(标准库)或NumPy。
列表包含符号
当从一个列表中生成一个新的列表时,列表理解法比for循环更容易编写。
- 相关的。如何使用Python的列表理解法
[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相混淆,但如果你了解列表理解符号和三元操作符的语法形式,就不难理解。
Starts with a specific string (以一个特定的字符串开始) (不开始)。: startswith()
如果字符串以参数中指定的字符串开始,则字符串方法startwith()返回真。
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']
Ends with a specific character string (不结束)。: endswith()
如果字符串与参数中指定的字符串结束,则字符串方法 endswith()返回真。
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']