首页 > 解决方案 > 嵌套python列表和字典问题的问题

问题描述

我是python的初学者。我有一个代码,但我只能理解其中的一部分。你能解释一下最后一行调用命令的细节吗?另外,为什么我们在 pop() 函数中传递 li:list 作为参数?

def insert(ls,params):
    ls.insert(int(params[0]), int(params[1]))

def print_list(ls, params):
    print(ls)

def remove(ls, params):
    ls.remove(int(params[0]))

def append(ls, params):
    ls.append(int(params[0]))

def sort_list(ls, params):
    ls.sort()

def pop(ls: list, params):
    ls.pop()

def reverse(ls, params):
    ls.reverse()

commands = {
    'insert': insert,
    'print': print_list,
    'remove': remove,
    'append': append,
    'sort': sort_list,
    'pop': pop,
    'reverse': reverse
}

if __name__ == '__main__':
    N = int(input())

    ls = []

    for _ in range(N):
        cmd = input().split(' ')
        commands[cmd[0]](ls, cmd[1:])

标签: pythonpython-3.xlist

解决方案


哦,好吧,让我们开始吧。我首先要说这不是惯用的代码,也不是任何熟练的 Python 程序员构建程序的方式。这就是说:分析它是有好处的。

逆向工作:让我们谈谈

为什么我们在 pop() 函数中传递 li:list 作为参数

你说的是我假设这里的函数声明

def pop(ls: list, params):
    ls.pop()

这称为函数注释,并在此处记录。它们通常用作类型提示,Python 运行时将它们完全剥离。使用或省略函数注释不会改变任何行为。

现在是肉和土豆:

你能解释一下最后一行吗

cmd = input().split(' ')
commands[cmd[0]](ls, cmd[1:])

这两条线是密不可分的。第一个调用input询问用户要运行什么,然后将其拆分为空格以生成字符串列表。例如,这可能是:

# user-input: append 3 4 5 6 7
cmd == ['append', '3', '4', '5', '6', '7']

然后下一行抓取该列表的第一个元素并查找该名称的命令,这是一个函数

commands[cmd[0]]

并调用它,将列表本身作为参数传入,其余参数则来自用户输入

                (ls, cmd[1:])

在我的示例中,这会导致调用如下所示:

append(lst, ['3', '4', '5', '6', '7'])

如果我要重写它,我会质疑它的相关性。似乎很多内部结构都暴露给了用户。如果确信有必要,我会将list.__getattribute__方法名称与这些方法配对。

# replacing all the function definitions and the "commands" dict:

def get_method(lst: list, attrname: str):
    try:
        method = lst.__getattribute__(attrname)
    except AttributeError:
        return None

然后将命令名称与内联参数分开,并在调用该方法之前检查该方法是否存在。

if __name__ == '__main__':
    n = int(input())
    lst = []
    for _ in range(n):
        cmd, *args = input().split(' ')

        method = get_method(lst, cmd)
        if method is not None:
            method(*args)

推荐阅读