16.3. 重识列表过滤

你已经熟识了应用列表解析来过滤列表。这里介绍的是达到相同效果的另一种令很多人感觉清晰的实现方法。

Python 有一个内建 filter 函数,它接受两个参数:一个函数和一个列表,返回一个列表。[12] 作为第一个参数传递给 filter 的函数本身应接受一个参数,filter 返回的列表将会包含被传入列表参数传递给 filter 所有可以令函数返回真 (true) 的元素。

都明白了吗?并没有听起来那么难。

例 16.7. filter 介绍

>>> def odd(n):                 
...     return n % 2
...     
>>> li = [1, 2, 3, 5, 9, 10, 256, -3]
>>> filter(odd, li)             
[1, 3, 5, 9, -3]
>>> [e for e in li if odd(e)]   
>>> filteredList = []
>>> for n in li:                
...     if odd(n):
...         filteredList.append(n)
...     
>>> filteredList
[1, 3, 5, 9, -3]
odd 使用内建的取模 (mod) 函数 “%” 对于为奇数的 n 返回 1;为偶数的返回 0
filter 接受两个参数:一个函数 (odd) 和一个列表 (li)。它依列表循环为每个元素调用 odd 函数。如果 odd 返回的是真 (记住,Python 认为所有非零值为真),则该元素被放在返回列表中,如若不然则被过滤掉。结果是一个只包含原列表中奇数的列表,出现顺序则和原列表相同。
你可以通过遍历的方式完成相同的工作,正如在 第 4.5 节 “过滤列表” 中看到的。
你可以通过 for 循环的方式完成相同的工作。取决于你的编程背景,这样也许更“直接”,但是像 filter 函数这样的实现方法更清晰。不但编写简单,而且易于读懂。for 循环就好比近距离的绘画:你可以看到所有的细节,但是或许你应该花几秒时间退后几步看一看图画的全景:“啊,你仅仅是要过滤列表!

例 16.8. regression.py 中的 filter

    files = os.listdir(path)                                
    test = re.compile("test\.py$", re.IGNORECASE)           
    files = filter(test.search, files)                      
正如你在 第 16.2 节 “找到路径” 中看到的,时时彩计划软件公式:path 可能包括正在运行脚本的完全或者部分路径名,或者当脚本运行自当前目录时包含一个空的字符串。任何一种情况下,files 都会获得正运行脚本所在目录的文件名。
这是一个预编译的正则表达式。正如你在 第 15.3 节 “重构”中看到的,如果你需要反复使用同一个正则表达式,你应该编译它已获得更快的性能。编译后的对象将含有接受一个待寻找字符串作为参数的 search 方法。如果这个正则表达式匹配字符串,search 方法返回一个包含正则表达式匹配信息的 Match 对象;否则返回 None,这是 Python 空 (null) 值。
对于 files 列表中的每个元素,你将会调用正则表达式编译对象 testsearch 方法。如果正则表达匹配,方法将会返回一个被 Python 认定为真 (true) 的 Match 对象;如果正则表达不匹配,search 方法将会返回被认定为假 (false) 的 None,元素将被排除。

历史注释. Python 2.0 早期的版本不包含 列表解析,因此不能 以列表解析方式过滤filter 函数是当时唯一的方法。即便是在引入列表解析的 2.0 版,有些人仍然钟情于老派的 filter (和这章稍后将见到的它的伴侣函数 map )。两种方法并存于世,使用哪种方法只是风格问题,mapfilter 将在未来的 Python 版本中被废止的讨论尚无定论。

例 16.9. 以列表解析法过滤

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)] 
这种方法将完成和 filter 函数完全相同的工作。哪种方法更清晰完全取决于你自己。

Footnotes

[12] 从技术层面上讲,filter 的第二个参数可以是任意的序列,包括列表、元组以及定义了 __getitem__ 特殊方法而能像列表一样工作的自定义类。在可能情况下,filter 会返回与输入相同的数据类型,也就是过滤一个列表返回一个列表,过滤一个元组返回一个元组。

时时彩注册送28元彩金 绑定机器码破解 重庆时时彩042期 重庆时时彩软件制作 江西时时彩杀号公式f
正规时时彩平台有哪些 重庆时时彩黑彩 多宝时时彩平台手机版 时时彩杀垃圾复式软件 入侵网站改时时彩骗局
时时彩银狐娱乐 时时彩计划给力标语 新时时彩走势 时时彩计划lm0 a彩娱乐平台在线登录
时时彩后三组选包胆 时时彩骗局揭秘 拉菲时时彩1950注册 时时彩任选二 时时彩黑平台曝光网
贵州快三 黑龙江十一选五任选四 山东快乐扑克3玩法 吉林快3,吉林快3大小单双走势 江西快3开奖历史开奖
体彩排列三开奖结果 北京pk10官网登陆 福建36选7开奖中奖规则 河北快三走势图最新 良辰讵可待txt下载
河北童装平台?河北快3一定牛?河北快3遗漏号查询 二分彩走势图 香港六合彩信息 浙江体彩网11选5 河北十一选五计划群
排列三计算器 浙江6加1玩法说明 新疆彩票35选7 幸运飞艇 快3走势图势图