#eg.查出字符串中每个词的首字母在整个字符串里的位置defindex_words(text):
result =[]if text:
result.append(0)for index,letter inenumerate(text):if letter ==' ':
result.append(index+1)return result
address ='Four score and seven years ago...'
result = index_words(address)print result
#使用生成器改写'''
生成器(generator)是用yield表达式的函数。
调用生成器时,它不会真的运行,只是返回迭代器。每次在该迭代器上调用内置的next时,迭代器会把生成器推进到下一个yield表达式那里。
生成器传给yield的每一个值,都会由迭代器返回给调用者
'''defindex_words_iter(text):if text:yield0for index,letter inenumerate(text):if letter ==' ':yield index+1#调用该生成器后所返回的迭代器,可以传给内置的list函数,将其转换为列表(参考第9条)
result =list(index_words_iter(address))print result
#同时index_words在返回前会把所有结果放在列表里,当输入量很大时就可能耗尽内存崩溃。#生成器改写后的版本可以应对任意长度的输入数据#eg.2.从文件里读入各行,逐个处理每行单词defindex_file(handle):
offset =0for line in handle:if line:yield offset
for letter in line:
offset+=1if letter ==' ':yield offset
withopen('xx,txt','r')as f:
it = index_file(f)
results = islice(it,0,3)printlist(results)###定义生成器函数时唯一需要注意的就是:函数返回的迭代器是有状态的,不能反复调用。
小心参数迭代(__iter__方法实现为生成器)
#迭代器智能产生一轮结果。在抛出过StopIteration异常的迭代器或生成器上继续迭代第二轮是不会有结果的#在已用完的迭代器上继续迭代不会报错...因为区分不了StopIteration异常是因为迭代器本来就没有输出值还是本来有但是用完了#解决方法:新编一种实现迭代器协议的容器类'''
pyhton在for循环及相关表达式中遍历某种容器的内容时,就要依靠这个迭代器协议。
在执行类似for x in foo这样的语句时,python实际上会调用iter(foo)。内置的iter函数又会调用foo.__iter__这个特殊方法。
该方法必须返回迭代器对象,而那个迭代器本身则实现了名为__next__的特殊方法。
此后,for循环会在迭代器对象上反复调用内置的next函数,直至耗尽并产生StopIteration异常。
'''classReadVisits(object):"""docstring for ReadVisits"""def__init__(self, data_path):
self.data_path = data_path
def__iter__(self):withopen(self.data_path)as f:for line in f:yieldint(line)'''
Python的迭代器协议,描述了容器和迭代器应该如何与iter与next内置函数、for循环及相关表达式相互配合。
把__iter__方法实现为生成器,即可定义自己的容器类型
想判断某个值是迭代器还是容器,可以拿该值为参数,两次调用iter函数,若结果相同,则是迭代器,调用内置的next函数,即可令该迭代器前进一步
'''
import time
#使用动态参数作为默认值#一般写法:deflog(message,when=time.asctime( time.localtime(time.time()))):#最简单的获取可读的时间模式的函数是asctime()print('%s: %s'%(when,message))
log('hi there!')
time.sleep(1)
log('hi again')#会发现两个消息时间一样#【因为】time.asctime只在函数定义的时候执行了一次#参数的默认值,只会在程序加载模块并读到本函数的定义时评估一次。#正确写法deflog2(message,when=None):
when = time.asctime( time.localtime(time.time()))if when isNoneelse when
print('%s: %s'%(when,message))
log2('hi there!')
time.sleep(1)
log2('hi again')'''
>>输出:
Fri Mar 17 15:18:38 2017: hi there!
Fri Mar 17 15:18:38 2017: hi again
Fri Mar 17 15:18:39 2017: hi there!
Fri Mar 17 15:18:40 2017: hi again
'''#对于以动态值作为实际默认值的关键字参数来说,应该把形式上的默认值写为None,并在函数的文档字符串里描述该默认值对应的实际行为