Python 迭代器、生成器、递归、正则表达式 (四)
一、迭代器&生成器
1、迭代器仅仅是一容器对象,它实现了迭代器协议。它有两个基本方法:
1)next 方法 返回容器的下一个元素
2)_iter_方法 返回迭代器自身。迭代器可以使用内建的iter方法创建
ts = iter(['asd','sds','qweq'])
#创建iter方法
print(ts.__next__())
#使用_next_方法返回下一个元素
print(ts.__next__())
print(ts.__next__()) #运行结果
asd
sds
qweq
#需要注意的是,如果已经全部返回后,多输出一个next的话报错
Traceback (most recent call last):
print(ts.__next__())
StopIteration
2、生成器
通过list可以直接创建一个列表,但是收到内存限制,列表容量肯定是有限。而且,创建一个包含几千万元素的列表肯定会占用很大的存储空间。如果要访问前面的几个元素,那么后面绝大多数元素占得空间都浪费了。
所以,如果列表元素可以按照某种算法推算出来,就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。一边循环一边计算的机制,称为生成器:generator。
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器,如果函数中包含yield语法,那这个函数就会变成生成器
def cash(m):
while m > 0:
m -=1
yield 100
print('取钱')
atm = cash(300)
print(type(atm))
print(atm.__next__())
print(atm.__next__())
print('待会............')
print(atm.__next__())
#运行结果
<class 'generator'>
100
取钱
100
待会............
取钱
100
作用:yield的主要效果就是可以使函数中断,并保存中断状态;中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另一种用途就是可以通过yield实现在单线程的情况下实现并发运算的效果。
import time
def consumer(name):
print('%s,过来吃饭' %name)
while True:
baozi = yield
print('包子[%s]来了,被[%s]吃了' %(baozi,name))
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print('开始做饭了')
for i in range(10):
time.sleep(1)
print('做了2个包子')
c.send(i)
c2.send(i)
producer('tom')
#运行结果
A,过来吃饭
B,过来吃饭
开始做饭了
做了2个包子
包子[0]来了,被[A]吃了
包子[0]来了,被[B]吃了
做了2个包子
包子[1]来了,被[A]吃了
包子[1]来了,被[B]吃了
做了2个包子
包子[2]来了,被[A]吃了
包子[2]来了,被[B]吃了
做了2个包子
包子[3]来了,被[A]吃了
包子[3]来了,被[B]吃了
做了2个包子
包子[4]来了,被[A]吃了
包子[4]来了,被[B]吃了
做了2个包子
包子[5]来了,被[A]吃了
包子[5]来了,被[B]吃了
做了2个包子
包子[6]来了,被[A]吃了
包子[6]来了,被[B]吃了
做了2个包子
包子[7]来了,被[A]吃了
包子[7]来了,被[B]吃了
做了2个包子
包子[8]来了,被[A]吃了
包子[8]来了,被[B]吃了
做了2个包子
包子[9]来了,被[A]吃了
包子[9]来了,被[B]吃了
二、装饰器
1、嵌套函数
def t1(a):
def t2(b):
return a+b
return t2
f = t1('aaaa_')
res = f('bbbbbb')
print(res)
#运行结果
aaaa_bbbbbb
运行流程:
1)由于程序是由上到下的执行顺序,所以首先执行“f = t1('aaaa_');
2)把a的值传给函数t1,a='aaaa_',但是该函数里面又包含另一个函数,所以先跳出;
3)执行res = f('bbbbb'),把'bbbbb'赋值给函数t2,b = 'bbbbb';
4)执行t2,返回a+b,print输出结果。
进阶
def action(x):
return(x) def action_pro(n):
def warpper(x):
return(n(x) * x)
return(warpper) action = action_pro(action) #第一个action为自定义的伪装变量,第二个action为上边定义的action函数
res = action(3) #此函数实际为warpper(3),返回值为9
print(res)
#运行结果9
def action_pro(n):
def warpper(x):
return(n(x) * x)
return(warpper) @action_pro #用action_pro函数把action包装成warpper
def action(x):
return(x) action(3) #此函数实际为warpper(3),返回值为9
def login(func):
def inner(arg):
print('Success!')
func(arg)
return inner
@login
def tv(name):
print('welcome [%s] to page!'%name) #tv = login(tv)
tv('tom')
三、递归
递归算法是一种直接或者间接的调用自身算法的过程。
特点:
1、递归就是在过程或函数里调用自身;
2、在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口;
3、在递归条用的过程当系统为每一层的返回点、局部变量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不使用递归算法设计程序。
要求:
1、每次调用在规模上都有所缩小;
2、相邻两次重复之间有紧密的联系,前一次为后一次做准备(通常前一次的输出作为后一次的输入);
3、每次递归调用都是有条件的,无条件的递归将会成为死循环。
示例:
def calc(n):
print(n)
if n/2 > 1:
res = calc(n/2)
print('res',res)
print('N',n)
return n
calc(10)
进阶:快速判断一个数字是否在一个列表中
def search(data_soure,find_n):
mid = int(len(data_soure)/2)
print(len(data_soure))
if len(data_soure) >=1:
if data_soure[mid] > find_n:
print('in left')
# print(data_soure[:mid])
search(data_soure[:mid],find_n)
elif data_soure[mid] < find_n:
print('in right')
# print(data_soure[mid:])
search(data_soure[mid:],find_n)
else:
print('Found in!')
else:
print('No!')
if __name__ == '__main__':
data = list(range(1,10000000))
search(data,1)
四、算法基础
备注:下次细说
要求:生成一个4*4的2维数组并将其顺时针旋转90度
data = [[col for col in range(4)] for row in range(4)]
for r_index,row in enumerate(data):
for c_index in range(r_index,len(row)):
tmp = data[c_index][r_index]
data[c_index][r_index] = row[c_index]
data[r_index][c_index] = tmp
print('*****************')
for r in data:print(r)
五、正则表达式
Python通过re模块提供对正则表达式的支持。使用re的步骤一般是先将表达式的字符串形式编译为pattern实例,然后使用pattern实例处理文本并获得匹配结果,最后使用match实例获得信息,进行其他的操作。
import re # 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello') # 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!') if match:
# 使用Match获得分组信息
print(match.group())
#运行结果
hello
re.match函数
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
re.search('\d+\.?\d*[\*\/]+[\+\-]?\d+\.?\d*',raw)
#检查是否包含‘*’,‘/’
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
检索和替换
Python 的re模块提供了re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, max=0)
返回的字符串是在字符串中用 RE 最左边不重复的匹配来替换。如果模式没有发现,字符将被没有改变地返回。
可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 表示替换所有的匹配。
raw = re.sub('\s','',raw)
#替换掉所有空格
Python 迭代器、生成器、递归、正则表达式 (四)的更多相关文章
- Python迭代器生成器与生成式
Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- Python 迭代器&生成器
1.内置参数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice ...
- python 迭代器 生成器
迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- python迭代器,生成器,推导式
可迭代对象 字面意思分析:可以重复的迭代的实实在在的东西. list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定) 专业角度: ...
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- Python迭代器,生成器,装饰器
迭代器 通常来讲从一个对象中依次取出数据,这个过程叫做遍历,这个手段称为迭代(重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值). 可迭代对象(iterable):是指该对象可以被 ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- python迭代器生成器
1.生成器和迭代器.含有yield的特殊函数为生成器.可以被for循环的称之为可以迭代的.而可以通过_next()_调用,并且可以不断返回值的称之为迭代器 2.yield简单的生成器 #迭代器简单的使 ...
- Python迭代器生成器,私有变量及列表字典集合推导式(二)
1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getatt ...
随机推荐
- Yii2.0中文开发向导——删除数据
直接 model 删除 $model = User::find($id); $model->delete(); 带有条件的删除 $connection ->createCommand() ...
- JetBrains PhpStorm 使用
· 在左侧显示当前文件位置 在左侧显示当前文件位置 alt + F1 在选择第1个在文件夹显示文件 在文件标签上 ctrl + 鼠标左键 或者 alt + F1 在选择第8个显示当前文件的函数,变量 ...
- shopnc b2b2c如何开启伪静态??
shopnc b2b2c开启伪静态的方法 一. windows环境下 1.先下载isapi rewrite插件,安装,然后我们把根目录下面的htaccess.txt那么修改成.htaccess即可. ...
- Core 发布至Linux
ASP.NET Core 发布至Linux生产环境 Ubuntu 系统 ASP.NET Core 发布至Linux生产环境 Ubuntu 系统,之前跟大家讲解了 dotnet publish 发布,而 ...
- 如何将windows版的vim界面语言(默认为中文)设置成英文
用安装包安装windows版本的vim(下载地址:http://www.vim.org/download.php),vim会自动根据windows的语言设置vim的界面语言.如何将其改为英文呢? 在v ...
- sql语法复习:增删查改,各种数据库对象创建和函数使用
推荐工具:机子配置较低的话,可以装Gsql这个工具获得sql执行环境(可作为手册查看内置数据类型 函数和存储过程等) --之前数据库的东西接触不多,虽然基本的语法是了解,但不是很熟悉--最近项目一直在 ...
- 挺有意思的Blog
http://blog.csdn.net/dawanganban/article/details/19925449 http://www.syslog.org/ https://baoz.net/li ...
- java学习之jdbc的封装
jdbc是连接数据库必不可少的工具,但每次连接都要重新写一遍太麻烦了,也不利于代码的可读性,这里做一个工具类进行封装. package com.gh; import java.sql.Connecti ...
- 用Jetty和redis实现接入服务器adapter
传统的服务器端为若干个客户端提供服务,一般需要开启多个服务器端进程.为了进一步提升服务器端的处理能力,可以如下图所示将服务解耦为两部分(adapter与workers),它们之间通过消息队列传输数据, ...
- .net c# 提交包含文件file 的form表单 获得文件的Stream流
1.前台html代码 要写一个有id的form,可是不能有runat="server"属性.由于一个页面中,有这个属性的form表单仅仅能有一个. 再要有一个有name的ifram ...