按关键词阅读:
1、一个输入序列(Input Sequence) 2、一个变量 , 代表着输入序列的一个成员(Variable) 3、一个可选的判定表达式 , 表达这个变量满足的条件(Optional Predicate ) 4、一个输出序列 , 根据 2 和 3 生成一个输出序列(Output Expression)
比如有个列表既有数字 , 又有字符 , 现在需要计算数字的平方 , 并将结果放在新的列表中 , 如果不用列表推导式 , 写出的代码就是这样的:
# bad codea_list = [1, ‘4’, 9, ‘a’, 0, 4] squared_ints = []for item in a_list:if type(item) == types.IntType:squared_ints.append(item**2)如果使用列表推导式 , 只需要两行代码 , 非常的优雅:
a_list = [1, ‘4’, 9, ‘a’, 0, 4]squared_ints = [ e**2 for e in a_list if type(e) == types.IntType ]
文章插图
当然 , 如果你喜欢 map 和 filter , 你还可以这样做 , 当时这是不推荐的 , 因为可读性不好:
map(lambda e: e**2, filter(lambda e: type(e) == types.IntType, a_list))比如集合推导式的使用:
给定输入
names = [ 'Bob', 'JOHN', 'alice', 'bob', 'ALICE', 'J', 'Bob' ]希望得到:
{ 'Bob', 'John', 'Alice' }那么集合推导式就是:
{ name[0].upper() + name[1:].lower() for name in names if len(name) > 1 }再比如字典推导式:
mcase = {'a':10, 'b': 34, 'A': 7, 'Z':3} mcase_frequency = { k.lower() : mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys() } # mcase_frequency == {'a': 17, 'z': 3, 'b': 34}从上面可以看出 。 推导式风格的代码是优雅的 , 人类易读的 。
四、你还在显式的关闭文件吗?如果你在写代码时仍然在显式的关闭文件 , 就像上图中的 programmer , 你在为编程语言工作 , 如果你学会了使用 with 上下文管理器 , 那么你就是一个 Python programmer , 让编程语言为你工作:
with open('filename.txt', 'w') as filename:filename.write('Hello')当程序退出 with 块时 , 文件会自动关闭 。 with 语句的语法格式:
with VAR as EXPR:BLOCK相当于:
mgr = (EXPR)exit = type(mgr).__exit__# Not calling it yetvalue = http://kandian.youth.cn/index/type(mgr).__enter__(mgr)exc = Truetry:try:VAR = value# Only if"as VAR" is presentBLOCKexcept:# The exceptional case is handled hereexc = Falseif not exit(mgr, *sys.exc_info()):raise# The exception is swallowed if exit() returns truefinally:# The normal and non-local-goto cases are handled hereif exc:exit(mgr, None, None, None) 有很多网络连接、数据库连接库都会提供 with 功能 。 甚至熟悉了 with 的实现机制后 , 可以自行实现 with 功能:
class File(object):def __init__(self, file_name, method):self.file_obj = open(file_name, method)def __enter__(self):return self.file_objdef __exit__(self, type, value, traceback):self.file_obj.close()只要定义了 __enter__,__exit__方法 , 就可以使用 with 语句:
with File('demo.txt', 'w') as opened_file:opened_file.write('Hola!')五、使用迭代器和生成器迭代器:iterator 生成器:generator
迭代器和生成器都是 Python 中功能强大的工具 , 值得精通 。 迭代器是一个更笼统的概念:任何一个对象只要它所属的类具有__next__方法(Python 2是next)和具有返回 self 的__iter__方法都是迭代器 。
每个生成器都是一个迭代器 , 但反之不然 。 生成器是通过调用具有一个或多个 yield 表达式的函数而构建的 , 并且该函数是满足上一段对iterator 的定义的对象 。
使用区别:
网络上很多技术博主都说生成器是懒人版的迭代器 , 比迭代器更节省内存 , 其实是错误的 , 他们都很节省内存(我会举例子) 。
他们真正的区别是:当你需要一个具有某些复杂的状态维护行为的类 , 或者想要公开除__next__(和__iter__和__init__)之外的其他方法时 , 你就需要自定义迭代器 , 而不是生成器 。
通常 , 一个生成器(有时 , 对于足够简单的需求 , 一个生成器表达式)就足够了 , 并且它更容易编写代码 。
比如说计算正整数 a 到 b (b 远远大于 a)直接的平方 , 生成器的话就是:
def squares(start, stop):for i in range(start, stop):yield i * i generator = squares(a, b)或者:
generator = (i*i for i in range(a, b))如果是迭代器 , 则是这样:
class Squares(object):def __init__(self, start, stop):self.start = startself.stop = stopdef __iter__(self): return selfdef __next__(self): # next in Python 2if self.start >= self.stop:raise StopIterationcurrent = self.start * self.startself.start += 1return current iterator = Squares(a, b)
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111J2N0H020.html
标题:如何写出更具有Python风格的代码,五分钟教会你( 二 )