知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516
全部博文(315)
分类: Python/Ruby
2012-02-22 21:26:25
不知不觉已经到了python核心编程第八章了,或许python本身没有学好,不过里面很多内容都相通了很多以前学过的知识,突然感觉除非你的知识掌握的非常牢固才可能很厉害。就像以前高中,一旦不会的问题,我都会记下来,然后去问 老师, 时间久了,懂的就多了。又感慨了,还不如行动了!......................
11.continue(尽量不放过每个小点)
From:不管是 Python, C, Java 还是其它任何支持 continue 语句的结构化语言中, 一些初学者有这样
的一个误解:continue 语句"立即启动循环的下一次迭代". 实际上, 当遇到 continue 语句时, 程
序会终止当前循环,并忽略剩余的语句, 然后回到循环的顶端. 在开始下一次迭代前,如果是条件循
环, 我们将验证条件表达式.如果是迭代循环,我们将验证是否还有元素可以迭代. 只有在验证成功
的情况下, 我们才会开始下一次迭代.
12.迭代器
迭代器它为类序列对象提供了一个类序列的接口. 对于序列而言,它们是一组数据结构,你可以利用它们的索引从 0 开始一直
"迭代" 到序列的最后一个条目.,不过这是通过索引来做的,而我们的迭代器是一种接口,里面有可以迭代访问数据的next()来获取数据。迭代器可以有更高效的性能,如果你得到的返回值是一个序列,这样会占用内存来存放这样的序列对象。如果是一个迭代器,它在for循环或者其他地方来做,这样可以更加高效的访问和存储数据,我是这样理解的!
From: Python 的迭代无缝地支持
序列对象, 而且它还允许程序员迭代非序列类型, 包括用户定义的对象.
迭代器用起来很灵巧, 你可以迭代不是序列但表现出序列行为的对象, 例如字典的 key , 一个
文件的行, 等等. 当你使用循环迭代一个对象条目时, 你几乎不可能分辨出它是迭代器还是序列.
你不必去关注这些, 因为 Python 让它象一个序列那样操作.
简单实例1:(举这个简单的例子,了解下迭代器这个概念,同时熟悉下前面接触过的try: except StopIteration; 随着深入就会更加明白)
#test.py
#!/usr/bin/env python
import itertools
seq = ('huanglei', 'dabing', 'kele')
itr = iter(seq)
if __name__ == '__main__':
while True:
try:
print itr.next()
except StopIteration:
break
简单实例2:(这个例子没什么特别的,字典那块特别点,就是在迭代过程中不能执行删除操作,不管字典是不是可变的,都不行,这点可以避免误删除的操作)
#file: file.py
#!/usr/bin/env python
if __name__ == '__main__':
myFile = open('test.py', 'r')
for eachLine in myFile:
print eachLine, #comma suppresses extra \n
myFile.close()
#dictionary
myDict = {'a':1, 'b':2, 'c':3}
for eachKey in myDict:
print eachKey, myDict[eachKey]
#in iteration, can't do like this.But we can del when your dictionary is changable;
#del myDict[eachKey]
13.列表解析
(List comprehensions,除此之外,生成器表达式也是列表解析,不过它是列表解析的一个扩展。
<生成器表达式与列表解析非常相似,而且它们的基本语法基本相同;不过它并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生”(yield)出来. 生成器表达式使用了"延迟计算"(lazy evaluation), 所以它在使用内存上更有效.--------读到这里我还是有点迷糊,只是知道它每次计算一个条目,不用一次性产生列表,我认为这样的话,你不需要的东西可以先不做,用完后可以释放掉,这样节约了很多内存,感觉理解的不太对?再查查.......>)
文章说是来自函数式编程,这个函数式编程?像map(), lambda(lambda 允许你快速地创建只有一行的函数对象), filter(filter() 基于一个条件表达式过滤列表成员)等就具有函数式编程的特性。说到map(),在前一章做的联系题那个加密练习就用到了map()这样的特性,但是只是用了translate()函数,我想还是有关系的哈!
列表解析案例:(刚开始看不太懂,这里自己注释下比较好哈)
案例1. 计算文件大小
/---这是利用函数
>>> import os
>>> os.stat('userpw2.0.py').st_size
3306L
/----这里用列表解析单词数
>>> f = open('userpw2.0.py', 'r')
>>> len([word for line in f for word in line.split()])
343
/---单词长度之和,利用sum
>>> f.seek(0)
>>> sum([len(word) for line in f for word in line.split()])
2266
/---单词长度和,利用sum,同时采用列表生成器,优化内存结构
>>> f.seek(0)
>>> sum(len(word) for line in f for word In line.split())
2266
案例2. 读取文件从一般化方法过渡到列表解析再过渡到生成器表达式,不断优化
1>
def read_file:
f = open('/etc/motd', 'r')
longest = 0
while True:
linelen = len(f.readline().strip())
if not linelen:
break
if linelen > longest:
longest = linelen
f.close()
return longest
2>
def read_file:
f = open('/etc/motd', 'r')
longest = 0
allLines = f.readlines()
f.close()
#提前关闭,节约系统资源
for line in allLines:
linelen = len(line.strip())
if linelen > longest:
longest = linelen
return longest
3>
def read_file:
f = open('/etc/motd', 'r')
longest = 0
allLines = [x.strip() for x in f.readlines()]
#这里strip()还要了解下...后面发现这是为了处理不同系统的结束符问题,比如在windows下是\n\r,在linux下是\n,所以要达到统一性.
f.close()
for line in allLines:
linelen = len(line.strip())
if linelen > longest:
longest = linelen
return longest
4>文件本身就是迭代器,而且我们之前也知道max可以以迭代器作为参数,所以就大大简化了代码
def read_file:
f = open('/etc/motd', 'r')
allLineLens = [len(x.strip()) for x in f]
f.close()
return max(allLineLens)
5>在4的基础上,还可以直接算出,然后返回
def read_file:
f = open('/etc/motd', 'r')
allLineLens = max(len(x.strip()) for x in f) #这里要用迭代器表达式
f.close()
return max(allLineLens)
6>最后,如果不严格要求,可以如此
return max(len(x.strip()) for x in open('/etc/motd'))
#这句最经典,把知识浓缩了