您当前位置: 首页 > 深入 Python > 自省的威力 > 过滤列表 | << >> | ||||
深入 Python从 Python 新手到专家 |
如您所知,Python 具有强大的功能,可以通过列表推导式将列表映射到其他列表(第 3.6 节,“映射列表”)。这可以与过滤机制结合使用,在过滤机制中,列表中的一些元素被映射,而其他元素则被完全跳过。
以下是列表过滤语法
[mapping-expression for element in source-list if filter-expression]
这是您熟悉和喜爱的列表推导式的扩展。前三分之二是相同的;最后一部分,从 if 开始,是过滤表达式。过滤表达式可以是任何计算结果为真或假的表达式(在 Python 中可以是几乎任何东西)。过滤表达式计算结果为真的任何元素都将包含在映射中。所有其他元素都将被忽略,因此它们永远不会通过映射表达式,也不会包含在输出列表中。
>>> 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__ 属性。
<< 使用 getattr 获取对象引用 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
and 和 or 的特殊性质 >> |