Dive Into Python 学习记录3-getattr 介绍/过滤列表/and or/lambda 函数
2012-07-26 16:20
911 查看
3.1getattr 介绍
3.2 过滤列表
这是你所知所爱的列表解析的扩展。前三部分都是相同的;最后一部分,以if 开头的是过滤器表达式。过滤器表达式可以是返回值为真或者假的任何表达式 (在
Python 中是几乎任何东西)。任何经过滤器表达式演算值为真的元素都可以包含在映射中。其它的元素都将忽略,它们不会进入映射表达式,更不会包含在输出列表中。
or 执行布尔逻辑演算,如你所期待的一样。但是它们并不返回布尔值,而是返回它们实际值;
3.3 and or
a :b 表达式,如果
bool 为真,表达式演算值为a,否则为 b。基于
Python 中 and 和
or 的工作方式,你可以完成相同的事情。
到现在为止,这个技巧可能看上去问题超过了它的价值。毕竟,使用 if 语句可以完成相同的事情,那为什么要经历这些麻烦事呢?哦,在很多情况下,你要在两个常量值中进行选择,由于你知道a 的值总是为真,所以你可以使用这种较为简单的语法而且不用担心。对于使用更为复杂的安全形式,依然有很好的理由要求这样做。例如,在Python 语言的某些情况下
if 语句是不允许使用的,比如在lambda 函数中。
那么 info 函数到底用这些 lambda 函数、split 函数和and-or 技巧做了些什么呢?
processFunc 现在是一个函数,但是它到底是哪一个函数还要取决于
collapse 变量。如果 collapse 为真,processFunc(string) 将压缩空白;否则processFunc(string)
将返回未改变的参数。
在一个不很健壮的语言中实现它,像 Visual Basic,你很有可能要创建一个函数,接受一个字符串参数和一个collapse 参数,并使用
if 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在Python 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的
lambda 函数提供确切的 (唯一的) 你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 (哦,想到那些参数就头昏) 的错误
>>> s.ljust(30)
'buildConnectionString '
>>> s.ljust(20)
'buildConnectionString'
>>> li = ["Larry", "Curly"] >>> li.pop <built-in method pop of list object at 010DF884> >>> getattr(li, "pop") <built-in method pop of list object at 010DF884> >>> getattr(li, 'pop')(3) 'why' >>> li ['hard', 'difficult', 'complex'] #也可以用 >>> getattr(li, "append")("Moe") >>> li ["Larry", "Curly", "Moe"] >>> getattr({}, "clear") <built-in method clear of dictionary object at 00F113D4> >>> getattr((), "pop") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'pop'
该语句获取列表的 pop 方法的引用。注意该语句并不是调用pop 方法;调用 pop 方法的应该是 li.pop()。这里指的是方法对象本身。 | |
该语句也是返回 pop 方法的引用,但是此时,方法名称是作为一个字符串参数传递给getattr 函数的。getattr 是一个有用到令人无法致信的内置函数,可以返回任何对象的任何属性。在这个例子中,对象是一个 list,属性是pop 方法。 | |
如果不确信它是多么的有用,试试这个:getattr 的返回值是 方法,然后你就可以调用它,就像直接使用li.append("Moe") 一样。但是实际上你没有直接调用函数;只是以字符串形式指定了函数名称。 | |
getattr 也可以作用于字典。 | |
理论上,getattr 可以作用于元组,但是由于元组没有方法,所以不管你指定什么属性名称getattr 都会引发一个异常。 |
[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']
or 执行布尔逻辑演算,如你所期待的一样。但是它们并不返回布尔值,而是返回它们实际值;
3.3 and or
例 4.15. and 介绍
>>> 'a' and 'b' 'b' >>> '' and 'b' '' >>> 'a' and 'b' and 'c' 'c'
例 4.16. or 介绍
>>> 'a' or 'b' 'a' >>> '' or 'b' 'b' >>> '' or [] or {} {} >>> def sidefx(): ... print "in sidefx()" ... return 1 >>> 'a' or sidefx() 'a' >>> '' or 'b' or 'd' 'b'
a :b 表达式,如果
bool 为真,表达式演算值为a,否则为 b。基于
Python 中 and 和
or 的工作方式,你可以完成相同的事情。
>>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0] ''
由于 [a] 是一个非空列表,所以它决不会为假。即使a 是0 或者'' 或者其它假值,列表[a] 也为真,因为它有一个元素。 |
if 语句是不允许使用的,比如在lambda 函数中。
3.4 使用 lambda 函数
>>> s = "this is\na\ttest" >>> print s this is a test >>> print s.split() ['this', 'is', 'a', 'test'] >>> print " ".join(s.split()) 'this is a test'
这是一个多行字符串,通过使用转义字符的定义代替了三重引号。\n 是一个回车,\t 是一个制表符。 | |
不带参数的 split 按照空白进行分割。所以三个空格、一个回车和一个制表符都是一样的。 | |
通过 split 分割字符串你可以将空格统一化;然后再以单个空格作为分隔符用 join 将其重新连接起来。这也就是info 函数将多行 doc string 合并成单行所做的事情。 |
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
processFunc 现在是一个函数,但是它到底是哪一个函数还要取决于
collapse 变量。如果 collapse 为真,processFunc(string) 将压缩空白;否则processFunc(string)
将返回未改变的参数。
在一个不很健壮的语言中实现它,像 Visual Basic,你很有可能要创建一个函数,接受一个字符串参数和一个collapse 参数,并使用
if 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在Python 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的
lambda 函数提供确切的 (唯一的) 你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 (哦,想到那些参数就头昏) 的错误
3.5 ljust 方法介绍
>>> s = 'buildConnectionString'>>> s.ljust(30)
'buildConnectionString '
>>> s.ljust(20)
'buildConnectionString'
ljust 用空格填充字符串以符合指定的长度。info 函数使用它生成了两列输出并将所有在第二列的doc string 纵向对齐。 | |
如果指定的长度小于字符串的长度,ljust 将简单地返回未变化的字符串。它决不会截断字符串。 |
相关文章推荐
- Dive Into Python 学习记录1-函数/模块导入/字典/列表/元组/字符串分割、连接、格式化/映射list/
- Dive Into Python 学习记录2-自省/info 函数 /str / type /callable 函数
- Dive Into Python 学习记录3-对获取某文件夹下MP3文件信息的代码构成分析
- python 函数-映射列表和过滤列表 学习
- python学习--列表函数
- Python学习笔记九:列表(1)--列表元素介绍及创建方法
- 【每日一记3.16】python学习记录3----字典,列表,元组
- Python入门学习记录——List(列表)
- Dive into python 实例学python (1) —— 函数和测试
- python学习记录 — (7)列表、元组、字典
- python核心编程学习记录之函数与函数式编程
- python学习记录--列表推导式
- 《DIVE INTO PYTHON》 学习PYTHON必备的入门利器
- Python学习_我该怎么使用函数及函数中传递列表
- python基础学习——列表(list), 元祖(tuple), 字典(dict), 字符串(string), 集合(set) 介绍及相互转换
- python网络数据采集学习范例—利用CSS爬取网站特定标签,BeautifulSoup函数介绍及子标签
- python 零散记录(五) import的几种方式 序列解包 条件和循环 强调getattr内建函数
- DayDayUP_Python自学记录[6]_函数学习
- 7、Python3 函数学习记录
- Python学习19:其他应用(列表综合、列表或元组作为函数参数、lambda形式)