使用match和case匹配模式完成一个简单的解释器,总体来说下面的解释器代码不太好理解,重点围绕模式匹配模块,理解模式匹配的作用及好处。
解释器代码:
普通匹配
case ['lambda',parms,*body] if body
该语句的params能够匹配任意参数,比如[],int,str,tuple等等
"""
简单介绍:procedure()自己实现的一个字符串输出函数
evaluate()解释器函数:
"""
def Procedure(x,y):
print(f'我是第params参数{x} | 我是body参数{y}')
#传入exp表达式,env环境参数
def evaluate(exp,env):
#将exp进行匹配
match exp:
#符合第一个拆包的为字符串quote
case ['quote',x]:
#返回x
return x
#符合第一拆包的为字符串if
case ['if',test,consequence,alternative]:
#实现递归调用evaluate()
if evaluate(test,env):
return evaluate(consequence,env)
else:
return evaluate(altenative,env)
case ['lambda',params,*body] if body:
return Procedure(params,body)
case ['define',Symbol() as name,value_exp]:
env[name]=evaluate(value_exp,env)
#如果都不匹配,抛出No
case _:
raise f'NO'
if __name__=='__main__':
#本次采用case ['lambda',params,*body] if body 方式进行匹配
#测试简单样例,不会报错,因为params这个位置上能够匹配上任何值
evaluate(['lambda','x',['*','x',2]],'expression')
限制性匹配:
case ['lambda',[*params],*body] if body
该params参数只能接受是列表类型的参数进行解包
def Procedure(x,y):
print(f'我是第params参数{x} | 我是body参数{y}')
def evaluate(exp,env):
match exp:
case ['quote',x]:
#返回x
return x
case ['if',test,consequence,alternative]:
if evaluate(test,env):
return evaluate(consequence,env)
else:
return evaluate(altenative,env)
case ['lambda',[*params],*body] if body:
return Procedure(params,body)
case ['define',Symbol() as name,value_exp]:
env[name]=evaluate(value_exp,env)
case _:
raise f'NO'
if __name__=='__main__':
#测试限制匹配
#样例会报错
"""
我们使用如下样例进行运行
"""
evaluate(['lambda','x',['*','x',2]],'expression')
我们发现上述主函数运行错误,原因是case中的[*params]和传递的参数'x'无法匹配,更改如下主函数试一下
def Procedure(x,y):
print(f'我是第params参数{x} | 我是body参数{y}')
def evaluate(exp,env):
match exp:
case ['quote',x]:
return x
case ['if',test,consequence,alternative]:
if evaluate(test,env):
return evaluate(consequence,env)
else:
return evaluate(altenative,env)
case ['lambda',[*params],*body] if body:
return Procedure(params,body)
case ['define',Symbol() as name,value_exp]:
env[name]=evaluate(value_exp,env)
case _:
raise f'NO'
if __name__=='__main__':
#这样子书写对于'lambda'更安全
#这里params对应的参数,加上【】,就可以匹配上
evaluate(['lambda',['x'],['*','x',2]],'expression')
切片对象:
深入学习python,发现了个之前没遇到过的切片操作,实现一个切片对象,使用方法如下:
可迭代对象:iter_object
切片对象:splice_object
操作:iter_object[splice_object] 返回被切片的可迭代对象
"""
发现切片对象对于文本中提取数据,对于数据清洗是很有用的
"""
代码样例:
"""
从invoice文本中提取到价格和描述信息
"""
invoice="""
0.....6..................................40..........52...55.....
1909 Pimoroni Pibrella $18.4 3 $53.3
1909 Pimoroni Pibrella $18.4 3 $53.3
1909 Pimoroni Pibrella $18.4 3 $53.3
1909 Pimoroni Pibrella $18.4 3 $53.3
1909 Pimoroni Pibrella $18.4 3 $53.3
"""
#使用slice对象,获取切片对象
SKU=slice(0,6)
DESCRIPTION=slice(6,40)
UNIT_PRICE=slice(40,52)
QUANTITY=slice(52,55)
ITEM_TOTAL=slice(55,None)
#数据清洗:通过给出的文段,除去第一行和第二行 (第一行为'\n',第二行为索引)
line_items=invoice.split('\n')[2:]
for item in line_items:
print(item[UNIT_PRICE],item[DESCRIPTION])
嵌套列表
相信大家或多或少都使用python做过关于迷宫算法相关的题型,最初认识python做题,斟酌于如何创建一个正确的迷宫地图,虽然创建对了,但不知道其中的相关原理。
对于自己先前创建二维迷宫地图是这样的:
内层为列数
外层为行数
PS:正确的地图,表示使用map[i][j]时只会改变一个列表单元
#创建迷宫地图 4行3列
your_map=[[0 for _ in range(3)] for _ in range(4)]
实例1:正确
#能够正确创建棋盘
#构建嵌套列表
board=[['_']*3 for _ in range(3)]
print(board)
board[1][2]='x'
print(board)
实例2:错误
"""不能再一个列表中3次引用同一个对象"""
board=[['_']*3]*3
print(board)
board[1][2]='o'
print(board)
#指向了同一个列表对象
那么看起来差不多的构建,为什么指向的引用对象不一样呢,解释如下:
#实例2错误代码等价于
#同一个rows像board追加了3次
row=['_']*3
board=[]
for _ in range(3):
#每次追加的都是同一个rows对象
board.append(row)
board[0][0]='X'
print(board)
#!!!!!列表推导式等价于以下代码
board=[]
for _ in range(3):
#每次迭代构建一个新的row
row=['_']*3
#每次追加的是不同的row对象
board.append(row)
board[0][0]='O'
print(board)
后序:
看到这里,可能各位uu又又又了解了几个不常用的知识点,后续会持续更新下饭知识点供uu们空闲时一览。