导航: 起始页 > Dive Into Python > 自省的威力 > 过滤列表 | << >> | ||||
Python 研究(Dive Into Python)Python 从新手到高手 [DIP_5_4_CPUG_RELEASE] |
如你所知,Python 具有通过列表解析(第 3.6 节 “映射 list”)将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素被映射的同时跳过另外一些元素。
过滤列表语法:
[mapping-expression for element in source-list if filter-expression]
这是你所知所爱的 列表解析 的扩展。前三部分都是相同的;最后一部分,以 if 开头的是过滤器表达式。过滤器表达式可以是返回值为真或者假(在 Python 中是 几乎任何东西)的任何表达式。任何经过滤器表达式演算值为元素的真都可以包含在映射中。其它的元素都将忽略,它们不会进入映射表达式,更不会包含在输出列表中。
例 4.14. 列表过滤介绍
>>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"] >>> [elem for elem in li if len(elem) > 1] ['mpilgrim', 'foo'] >>> [elem for elem in li if elem != "b"] ['a', 'mpilgrim', 'foo', 'c', 'd', 'd'] >>> [elem for elem in li if li.count(elem) == 1] ['a', 'mpilgrim', 'foo', 'c']
回到 apihelper.py 中的这一行:
methodList = [method for method in dir(object) if callable(getattr(object, method))]
这行看上去挺复杂的,确实也很复杂,但是基本结构都还是一样的。整个过滤表达式返回一个列表,并赋值给 methodList 变量。表达式的前半部分是列表映射部分。映射表达式是一个和遍历元素相同的表达式,因此它返回每个元素的值。dir(object) 返回 object 对象的属性和方法列表——你正在映射的列表。所以唯一新出现的部分就是在 if 后面的过滤表达式。
过滤表达式看上去很恐怖,其实不是。你已经知道了 callable、getattr 和 in。正如你在 前面的部分 中看到的,如果 object 是一个模块,并且 method 是上述模块中某个函数的名称,那么表达式 getattr(object, method) 将返回一个函数对象。
所以这个表达式接收一个名为 object 的对象,然后得到它的属性、方法、函数和其他部件的名称列表,接着过滤掉我们不关心的部件。执行过滤行为是通过对每个属性/方法/函数的名称调用 getattr 函数取得实际部件的引用,然后检查这些部件对象是否是可调用的,当然这些可调用的部件对象可能是方法或者函数,同时也可能是内置的(比如列表的 pop 方法)或者用户自定义的(比如 odbchelper 模块的 buildConnectionString 函数)。这里你不用关心其它的属性,如内置在每一个模块中的 __name__ 属性。
进一步阅读
- Python Tutorial 讨论了 使用内置过滤器函数 过滤列表的另一种方式。
<< 通过 getattr 获取对象引用 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
and 和 or 的特殊性质 >> |