筛选序列中的元素 --列表推导式、生成器表达式、filter()以及itertools.compress()

问题:根据指定条件筛选或删除序列中的一些元素

方法1:列表推导式

mylist = [1, 4, -5, 10, -7, 2, 3, -1]

[n for n in mylist if n>0]
Out[3]: [1, 4, 10, 2, 3]

import math
[math.sqrt(n) for n in mylist if n>0]   # 对数据做转换
Out[6]: [1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]

[n if n>0 else 0 for n in mylist]  # 筛选条件移到一个条件表达式
Out[7]: [1, 4, 0, 10, 0, 2, 3, 0]

[n for n in mylist if n>0 else 0]  # 错误写法❌
  File "", line 1
    [n for n in mylist if n>0 else 0]
                                 ^
SyntaxError: invalid syntax  

方法2:使用列表推导式的缺点是如果原始输入非常大的话,这么做可能会产生一个庞大的结果;因此可以使用生成器表达式通过迭代的方式产生筛选数据

pos = (n for n in mylist if n>0)
print(pos)  # 返回一个生成器对象
Out:  at 0x10d5ee780>
#  通过迭代的方式产生筛选数据
for p in pos:  
    print(p)
1
4
10
2
3

方法3:假如筛选过程涉及异常或者其他一些复杂的细节,可以将处理筛选逻辑的代码放到单独的函数中,然后使用内建的filter()函数处理

values = ['1', '2', '-3', '-', 'N/A', '5']
def is_int(val):
    try:
        x = int(val)
        return True
    except ValueError:
        return False
ivals = list(filter(is_int, values))  # filter()创建了一个迭代器,因此可以转换成list形式的结果
ivals
Out[11]: ['1', '2', '-3', '5']

方法4:使用itertools.compress(),接受一个可迭代对象以及一个布尔选择器序列作为输入;输出时,它会给出所有在相应布尔选择器中为True的可迭代对象元素

使用场景:如果想把对一个序列的筛选结果施加到另一个相关的序列上时,就会非常有用
address = ['shanghai', 'nanjing', 'shandong']
counts = [0, 1, 8]
# 想要构建一个地址列表,其中相应的count值要大于5
import itertools
more5 = [n>5 for n in counts]  # 返回一个布尔序列
more5
Out[13]: [False, False, True]
list(itertools.compress(address, more5))  # compress()创建了一个迭代器,因此可以转换成list形式的结果
Out[14]: ['shandong']

你可能感兴趣的:(筛选序列中的元素 --列表推导式、生成器表达式、filter()以及itertools.compress())