问题:根据指定条件筛选或删除序列中的一些元素
方法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 "<ipython-input-8-8e29d951d73d>", 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: <generator object <genexpr> 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']
网友评论