代码之家  ›  专栏  ›  技术社区  ›  Mr. Kelsey

如何从列表中返回字符串

  •  0
  • Mr. Kelsey  · 技术社区  · 5 年前

    我正在构建一个shell,我有一个用户输入命令。 如果该命令包含 * ?

    因为我用的是 subprocess 模块中,我的命令存储在列表中。使用管道,它可以成为一个列表列表。

    因此,我的数据可能以 [["first", "set", "of", "commands"],[["second", "set", "of", "commands"]]

    现在,让我们假设有一个 在其中一个命令中,我需要glob。 巨蟒 glob 模块返回一个列表。因此,如果我的用户输入 ls *.py 在一个包含3个python文件的目录中,globing将返回一个嵌套循环 ["ls, ["1.py", "2.py", "3.py"]] ["ls", "1.py", "2.py", "3.py"]

    我可以用下面的代码来实现,

    # commands is my list of lists
    for cmd in commands:
        for expr in cmd:
            if "*" in expr or "?" in expr:
                expr_index = cmd.index(expr)
                globbed = glob(expr)
                cmd[expr_index] = globbed.pop(0)
                for item in globbed:
                    cmd.insert(expr_index, item)
                    expr_index += 1
    

    现在,虽然它起作用了,但它就像罪一样丑陋,我觉得应该有更好的方法来做到这一点。

    如果我能做一些事情,比如:

    # again, commands is my list of lists
    globbed_commands = [
        [item for item in glob(expr) if "*" in expr or "?" in expr else expr for expr in cmd]
        for cmd in commands
    ]
    

    显然,这会引发语法错误。甚至可以使用列表理解来实现这一点吗?如果是,我还缺什么?

    0 回复  |  直到 5 年前
        1
  •  2
  •   juanpa.arrivillaga    5 年前

    这里最优雅的解决方案是简单地构建一个新的列表,而不是与索引混淆。

    globbed_commands = []
    for cmd in commands:
        new_cmd = []
        for expr in cmd:
            if "*" in expr or "?" in expr:
                new_cmd.extend(glob(expr))
            else:
                new_cmd.append(expr)
        globbed_commands.append(new_cmd)
    

    能够 做这样可怕的事情:

    globbed_commands = [
        [x for expr in cmd for x in (glob(expr) if "*" in expr or "?" in expr else [expr])]
        for cmd in commands
    ]
    

    但这正变得极不健康。使用辅助函数可能会变得可以忍受:

    def maybe_glob(expr):
        if "*" in expr or "?" in expr:
            return glob(expr)
        else:
            return [expr]
    
    
    globbed_commands = [
        [x for expr in cmd for x in maybe_glob(expr)]
        for cmd in commands
    ]
    

    但是我会使用上面的第一个for循环。