Day 4 Python之循序渐进4
1.迭代器原理及使用
迭代器原理:
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
不能随机访问集合中的某个值 ,只能从头到尾依次访问
访问到一半时不能往回退
便于循环比较大的数据集合,节省内存
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 # linux中的cat就类似于迭代的形势,读一行显示一行,减少内存利用率,速度快 5 6 names = iter(['leon','jack','list','offer']) 7 print(names) 8 print(names.__next__()) 9 print(names.__next__()) 10 print(names.__next__()) 11 print(names.__next__()) 12 # print(names.next()) 2.7这么写此方法
1 迭代器 2 作为遍历集合 ===,一般通过for循环间接使用 3 4 循环 5 1.while 6 索引,下标取数据,随意取值 7 2.for 8 a)执行迭代器,获取一个对象 9 b) 执行对象的next方法 10 11 引出: 12 iter(迭代器),获得一个具有next方法的对象 13 --->顺序去取 14 15 需求: 16 li = [11,22,33,44,55] 17 打印元素 18 19 i = len(li) 20 # i = 0 -->False,其他为Ture 21 start = 0 22 while i>start 23 print(li[start]) 24 start += 1 25 #while 使用索引(下标随意取数据),start为变量,所有的语言几乎都支持while循环的方式,但写起来麻烦 26 27 #于是出现for: 28 29 for item in li: 30 print(item) 31 32 obj = iter(li) 33 print(obj._next_()) 34 #使用本质,创建一个for循环 35 36 obj = iter(li) 37 while True: 38 try: 39 item = obj._next_() 40 print(item) 41 except Exception: 42 pass 43 44 45 #for循环的本质: 46 1.创建一个特殊的东西(迭代器),获取到一个具有next方法的对象 47 2.依据这个东西去操作列表li中的内容 48 49 50 迭代器 = iter() 51 执行迭代器返回一个对象,对象是含有next方法(操作列表中的内容)
2.生成器的使用
生成器generator
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
代码:
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 # 定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器 5 def cash_out(amount): 6 while amount >0: 7 amount -= 1 8 yield 1 # 注意与return的区别,yield退出循环又能再进去 9 print("擦,又来取钱了。。。败家子!") 10 11 ATM = cash_out(5) 12 13 print("取到钱 %s 万" % ATM.__next__()) 14 print("花掉花掉!") 15 print("取到钱 %s 万" % ATM.__next__()) 16 print("取到钱 %s 万" % ATM.__next__()) 17 print("花掉花掉!") 18 print("取到钱 %s 万" % ATM.__next__()) 19 print("取到钱 %s 万" % ATM.__next__()) 20 print("取到钱 %s 万" % ATM.__next__()) #到这时钱就取没了,再取就报错了 21 print("取到钱 %s 万" % ATM.__next__())
#! /usr/bin/env python # -*- coding:utf-8 -*- def cash_money(amount): while amount >0: amount -=100 yield 100 print("又来取钱了") # 注意与return的区别,yield退出循环又能再进去 atm = cash_money(500) print(type(atm)) print(atm.__next__()) print(atm.__next__()) print("断点插入,嘻哈测试") print(atm.__next__())
1 生成器yield (解决内存消耗) 2 """ 3 ******************************************************* 4 python 2.7 5 range, xrange 6 7 range(10) -->会在内存中create 0-9 8 xrange(10) --> 9 10 for i in xrange(10): 11 # 第一次循环内存中会创建0 12 # i = 0 13 # 第二次循环内存中会创建1 14 # i = 1 15 # 一直循环创建到9 16 print i 17 18 19 python 3 20 range 21 22 ******************************************************* 23 """ 24 """ 25 ******************************************************* 26 redis 27 28 n1 --> k1 = v1 29 k2 = v2 30 31 n2 --> k11 = v11 32 k12 = v12 33 34 监控:api http://baidu.com/p1 -->1,10 (1点的时候访问量是10) 35 -->2,30 36 redis -> hash 37 38 # 服务器缓存 100G 39 dic = {"k1":"v1","k2":"v2"} 40 41 # 本地电脑 2G 42 43 44 # 文件 45 f = open('f1.log') 46 # 把日志全部拿到内存 47 for line in f: 48 print(line) 49 ******************************************************* 50 """ 51 52 def show(): 53 yield 123 54 i = show() 55 print(i) 56 57 # 回想,文件操作 100G 58 f = open('f1.log') 59 for line in f: 60 print(line) 61 ******************************************************* 62 def show(): 63 yield 'line1' 64 yield 'line2' 65 yield 'line3' 66 my_f = show() 67 for line in my_f: 68 print(line) 69 # 函数如果含有yield,函数返回值就是特殊的东西(必须和for一起使用) 70 # for,函数返回的特殊值,函数内部执行代码,如果遇到yeild关键字,冻结当前状态,跳出函数回到for和特殊值位置 71 72 # 必须迭代方式执行生成器 73 # yield冻结状态(基础上一次执行位置),也具有next方法
3.使用yield实现单线程中的异步并发效果
作用:
yield的主要效果就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另外,还可通过yield实现在单线程的情况下实现并发运算的效果
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import time 5 def consumer(name): 6 print("%s 准备吃包子啦!" %name) 7 while True: 8 baozi = yield 9 10 print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) 11 12 def producer(name): 13 c = consumer('A') 14 c2 = consumer('B') 15 c.__next__() 16 c2.__next__() 17 print("开始准备做包子啦!") 18 for i in range(10): 19 time.sleep(1) 20 print("做了2个包子!") 21 c.send(i) # 通过send方法传给yield接收 22 c2.send(i) 23 24 producer("leon")
4.装饰器原理介绍和基本实现
装饰器的作用是给已经实现的功能再扩展新的功能
1 # 无参数执行 2 def login(func): # func = tv 3 print("passed user verification...") 4 # func() 5 return func #tv 6 # return None 7 8 def home(name): 9 print("Welcome [%s] to home page" %name) 10 # def tv(name): 11 def tv(): 12 print("Welcome [%s] to tv page") 13 def moive(name): 14 print("Welcome [%s] to moive page") 15 16 tv = login(tv) 17 tv()
5.装饰器实现
1 # 带参数执行 2 def login(func): # func = tv 3 def inner(arg): 4 print("passed user verification...") 5 func(arg) 6 return inner 7 8 def home(name): 9 print("Welcome [%s] to home page" %name) 10 # def tv(name): 11 @login #这种表示方法叫装饰器,也称语法堂 12 def tv(name): 13 print("Welcome [%s] to tv page"%name) 14 def moive(name): 15 print("Welcome [%s] to moive page") 16 17 # tv = login(tv) 18 tv("leon")
6.实现带参数的复杂装饰器
这个有点难理解
1 #!/usr/bin/env python 2 #coding:utf-8 3 4 def Before(request,kargs): 5 print 'before' 6 7 def After(request,kargs): 8 print 'after' 9 10 11 def Filter(before_func,after_func): 12 def outer(main_func): 13 def wrapper(request,kargs): 14 15 before_result = before_func(request,kargs) 16 if(before_result != None): 17 return before_result; 18 19 main_result = main_func(request,kargs) 20 if(main_result != None): 21 return main_result; 22 23 after_result = after_func(request,kargs) 24 if(after_result != None): 25 return after_result; 26 27 return wrapper 28 return outer 29 30 @Filter(Before, After) 31 def Index(request,kargs): 32 print 'index'
7.递归原理及实现
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def calc(n): 5 print(n) 6 if n/2 > 1: 7 res = calc(n/2) 8 print('res',res) 9 print("N:",n) 10 return n 11 calc(10)
8.通过递归实现斐波那契数列
1 # 通过递归实现斐波那契数列 2 3 def func(arg1,arg2,stop): 4 if arg1 == 0: 5 print(arg1,arg2) 6 arg3 = arg1 + arg2 7 print(arg3) 8 if arg3 < stop: 9 func(arg2,arg3,stop) 10 11 func(0,1,30)
9.算法基础之二分查找
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 def binary_seach(data_soure,find_n): 5 mid = int(len(data_soure)/2) 6 if len(data_soure) >= 1: 7 if data_soure[mid] > find_n: # 要找的值在左边 8 print("data in left of [%s]" %data_soure) 9 binary_seach(data_soure[:mid],find_n) 10 elif data_soure[mid] < find_n: 11 print("data in right of [%s]" %data_soure) 12 binary_seach(data_soure[mid:],find_n) 13 else: 14 print("found find_s,",data_soure[mid]) 15 else: 16 print("cannot find data") 17 18 if __name__ == '__main__': 19 data = list(range(1,6000000)) 20 # print(data) 21 binary_seach(data,65535)
10.算法基础之2维数组90度旋转
基础代码:
#! /usr/bin/env python # -*- coding:utf-8 -*- # a = [i for i in range(10)] = a.append(i) data = [[col for col in range(4)] for row in range(4)] for row in data: print(row) """ 输出:(二维数组) [0, 1, 2, 3] [0, 1, 2, 3] [0, 1, 2, 3] [0, 1, 2, 3] """
旋转90°解析思路:
实现:
11.正则表达式基础
正则表达式 import re
处理字符串
规则:
\s --> 空格
\d --> 数字
如:找到所有数字。1,2,3,4,5,6
\d 替换:所有数字 "alex"
分割: "adskfjaksdjfisad98sdf"
a)字符规则
b)次数规则
c)方法
match:从头开始匹配
search:从任意位置开始匹配
-->匹配结果:如果没有匹配到,范围None
-->匹配到了,则有两个方法group和groups:
group:
groups:
findall:
sub:替换
split:分组
1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import re 5 6 m = re.match("abc","abcdefg") 7 m = re.match("[0-9][0-9]","651abd3cdefg") 8 m = re.match("[0-9]{0,10}","651abd3cdefg") 9 m = re.match("[0-9]{10}","651abd3cdefg") 10 m = re.findall("[0-9]{1,10}","651abd3cdefg") 11 m = re.findall("[a-zA-z]{1,10}","651abd3cdefg") 12 m = re.findall(".*","651abd3cdefg") 13 m = re.findall(".+","651abd3cdefg") 14 m = re.findall("[a-zA-z]+","651abd3cdefg") 15 m = re.search("def","651abd3cdefg") 16 m = re.search("\d+","651abd3cdefg") 17 m = re.sub("\d+","|","651abd3cdefg") 18 m = re.search("^\d+$","651abd3cdefg") 19 m = re.search("^\d+$","14234812309482") 20 if m: 21 # print(m) 22 print(m.group()) 23 # 输出: 24 # <_sre.SRE_Match object; span=(0, 3), match='abc'> 25 26 # n = re.match("abc","defg") 27 # print(n) 28 # 输出:None