模式匹配实现解释器和切片对象和嵌套列表的正确使用——《流畅的python》

使用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们空闲时一览。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烧酒调调

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值