代码之家  ›  专栏  ›  技术社区  ›  Jonathan H

用xonsh列出理解

  •  3
  • Jonathan H  · 技术社区  · 6 年前

    我对这个还不熟悉,但是是否可以在 xonsh 使用列表理解语法?

    我希望下面创建五个文件 file00 file04 ,但它会出错:

    $ [@(['touch', 'file%02d' % i]) for i in range(5)]
    ............................ 
    xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
      File "<string>", line None
    SyntaxError: <xonsh-code>:1:1: ('code: @(',)
    [@(['touch', 'file%02d' % i]) for i in range(5)]
     ^
    

    我希望这能奏效,因为下面的工作很好:

    $ [i for i in range(5)]
    [0, 1, 2, 3, 4]
    
    $ @(['touch', 'file%02d' % 3])
    $ ls
    file03
    
    3 回复  |  直到 6 年前
        1
  •  2
  •   Jonathan H    6 年前

    最接近原始代码的方法是使用子流程:

    [$[touch @('file%02d' % i)] for i in range(5)]

    解释筑巢的必要性 $[ .. @( :

    • 顶层命令是一个列表理解,所以我们从python模式开始;
    • 我们要执行bash命令( touch )因此,我们需要使用 $[ (或) $( 捕捉输出);
    • 但是该命令的参数需要使用python进行字符串插值,因此python模式再次使用 @( .
        2
  •  2
  •   Gil Forsyth    6 年前

    看起来您找到了一种实现这一点的方法——有时特定子流程命令的行为会影响您将其组合在一起的方式。

    如果是 touch 因为它可以有多个参数,所以用列表理解(我能想到)来概括这一点最简单的方法是

    touch @([f'file_{i}' for i in range(5)])

        3
  •  1
  •   Jonathan H    6 年前

    我就快到了,有必要进一步总结一下命令:

    $ [ $(@(['touch', 'file%02d' % i])) for i in range(5)]
    

    原因如下:

    • 考虑到顶级命令是一个列表理解,我们进入了python模式。
    • 我们要执行bash命令( touch )因此,我们需要使用 $(
    • 但是,该命令的参数需要使用python进行字符串插值,因此编写命令本身需要python模式,因此 @(
    推荐文章