学习python 遇到的第一个问题 :过滤列表

引用Python 从新手到专家 

的例子:

def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.
    
    Takes module, class, list, dictionary, or string."""
    methodList = [method for method in dir(object) if callable(getattr(object, method))]
   'getattr(对象,方法,默认返回值) 是返回函数引用 ,相当于函数指针'
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)'这是一个函数引用,可以理解为函数指针'

  	 print "\n".join(["%s %s" %       '''字符串格式化'''
                      (method.ljust(spacing),
                       processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":            
    print info.__doc__


看到这段代码最让我困惑的地方就是:

methodList = [method for method in dir(object) if callable(getattr(object, method))]
    对于什么别的陌生的函数,直接help() 或者百度都能找到答案,但就这句话,让我怎么没明白什么意思,后来请教别人,别人就

给我推荐了一本书《python核心编程》 结果在一个鸟不拉屎的地方找到了,关于列表解析

4.5. 过滤列表

如你所知,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]       1
['mpilgrim', 'foo']
>>> [elem for elem in li if elem != "b"]         2
['a', 'mpilgrim', 'foo', 'c', 'd', 'd']
>>> [elem for elem in li if li.count(elem) == 1] 3
['a', 'mpilgrim', 'foo', 'c']
1这里的映射表达式很简单 (只是返回每个元素的值),所以请把注意力集中到过滤器表达式上。由于 Python 会遍历整个列表,它将对每个元素执行过滤器表达式。如果过滤器表达式演算值为真,该元素就会被映射,同时映射表达式的结果将包含在返回的列表中。这里,你过滤掉了所有单字符的字符串,留下了一个由长字符串构成的列表。
2这里你过滤掉了一个特定值 b。注意这个过滤器会过滤掉所有的 b,因为每次取出 b,过滤表达式都将为假。
3count 是一个列表方法,返回某个值在列表中出现的次数。你可以认为这个过滤器将从列表中剔除重复元素,返回一个只包含了在原始列表中有着唯一值拷贝的列表。但并非如此,因为在原始列表中出现两次的值 (在本例中,b 和 d) 被完全剔除了。从一个列表中排除重复值有多种方法,但过滤并不是其中的一种。

回到 apihelper.py 中的这一行:

    methodList = [method for method in dir(object) if callable(getattr(object, method))]

这行看上去挺复杂――确实也很复杂――但是基本结构都还是一样的。整个过滤表达式返回一个列表,并赋值给 methodList 变量。表达式的前半部分是列表映射部分。映射表达式是一个和遍历元素相同的表达式,因此它返回每个元素的值。dir(object) 返回 object 对象的属性和方法列表――你正在映射的列表。所以唯一新出现的部分就是在 if 后面的过滤表达式。

过滤表达式看上去很恐怖,其实不是。你已经知道了 callablegetattr 和 in。正如你在前面的部分中看到的,如果 object 是一个模块,并且 method 是上述模块中某个函数的名称,那么表达式 getattr(object, method) 将返回一个函数对象。

所以这个表达式接收一个名为 object 的对象,然后得到它的属性、方法、函数和其他成员的名称列表,接着过滤掉我们不关心的成员。执行过滤行为是通过对每个属性/方法/函数的名称调用getattr 函数取得实际成员的引用,然后检查这些成员对象是否是可调用的,当然这些可调用的成员对象可能是方法或者函数,同时也可能是内置的 (比如列表的 pop 方法) 或者用户自定义的 (比如 odbchelper 模块的 buildConnectionString 函数)。这里你不用关心其它的属性,如内置在每一个模块中的 __name__ 属性。



def info(object, spacing=10, collapse=1): 1 2 3
    """Print methods and doc strings.
    
    Takes module, class, list, dictionary, or string."""
    methodList = [method for method in dir(object) if callable(getattr(object, method))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                      (method.ljust(spacing),
                       processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":                4 5
    print info.__doc__
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值