来源《python cookbook》第三版
问题:如果有序列,基于某些规则从中提取元素或者更改序列。
一、过滤数据
1.1 最简单的是基于列表推导
mylist = [1, 4, 3, -5, 0, -11, -9]
[n for n in mylist if n>0]
缺陷在于如果列表非常大,会长生巨大的结果集占用大量内存。若果对内存敏感,使用生成器表达式迭代元素。
pos = (n for n in mylist if n>0)
for x in pos:
print(x)
1.2 如果规则比较复杂,比如需要处理异常等,可以将代码放入函数中,内建filter()函数
values = ['1', '2', '-3', '-', '4', 'N/A', '5']
def is_int(val):
try:
x = int(val)
return True
except ValueError:
return False
ivals = list(filter(is_int, values))
print(ivals)
# Outputs ['1', '2', '-3','4', '5']
二、过滤时添加转换
>>>L = ['helLLO', 'World', 18, 'applE', None]
>>>[s.lower() for s in L if isinstance(s, str)]
# Outputs ['helllo', 'world', 18, 'apple', None]
# 2
>>>[s.lower() if isinstance(s, str) else s for s in L]
在for循环中,如果if条件通过则执行s.lower(),否则else执行s(不做变化)
三、另一种值得关注的过滤工具itertools.compress()
>>>addresses = [
'5412 N CLARK',
'5148 N CLARK',
'5800 E 58TH',
'2122 N CLARK'
'5645 N RAVENSWOOD',
'1060 W ADDISON',
'4801 N BROADWAY',
'1039 W GRANVILLE',
]
>>>counts = [ 0, 3, 10, 4,1,7, 6, 1]
提取counts大于5的地址
>>>from itertools import compress
>>>more5 = [n > 5 forn in counts]
>>>more5
[False, False, True, False, False, True, True, False]
>>>list(compress(addresses, more5))
['5800 E 58TH', '4801 NBROADWAY', '1039 W GRANVILLE']
>>>