V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
AndyAO
V2EX  ›  Python

挑战:获取文件夹中 Python 文件并使用其文件名生成数组字面量字符串

  •  
  •   AndyAO · 2021-05-05 09:52:26 +08:00 · 2132 次点击
    这是一个创建于 1333 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如,当前脚本根目录的文件夹 Action 中有 .py 文件:

    那么运行的结果就是生成 "A","B","C","D"。

    最近一直在用 PowerShell,发现这个需求在 PowerShell 中的实现惊人的简洁。

    别的编程语言,还能用自带的库函数,写出比这更简洁又具有可读性的代码吗?

    如果你觉得还可以,欢迎来挑战。

    "$PSScriptRoot\Action" | dir -File -Filter '*.ps1'|% BaseName | Join-String -DoubleQuote -Separator ','
    
    第 1 条附言  ·  2021-05-05 12:25:26 +08:00
    1. 感觉目前的答案中感觉 Ruby 的可读性最好

    2. 过滤器参数是不必要的,所以可以改为

    ("$PSScriptRoot\Action" | dir '*.ps1' -File).BaseName | Join-String -Separator ',' -DoubleQuote 
    
    1. Join-String -Separator ',' -DoubleQuote 可以使用符号缩短,对于我而言那会降低可读性,所以并没这么
    第 2 条附言  ·  2021-05-05 13:14:56 +08:00

    上个追加写错了,路径参数传递了两遍,刚刚才发现,其实应该是

    ("$PSScriptRoot\Action\*.ps1" | dir -File).BaseName | Join-String -Separator ',' -DoubleQuote

    FH0
        1
    FH0  
       2021-05-05 10:04:13 +08:00   ❤️ 1
    ```bash
    echo -e "A.py\nB.py\nC.py\nD.py" | awk -F '.py' '{printf "\"" $1 "\","}' | sed 's|,$||'
    ```
    aloxaf
        2
    aloxaf  
       2021-05-05 10:31:45 +08:00   ❤️ 1
    ```zsh
    echo \"${(j:",":)${(A)=:-$(print *.py(:r))}}\"
    ```

    简洁,并且具有可读性(确信
    aloxaf
        3
    aloxaf  
       2021-05-05 10:36:16 +08:00
    ```zsh
    f=(*.py(:r));echo \"${(j:",":)f}\"
    ```

    比起强行塞到一个表达式里写成两段好像更好(
    msg7086
        4
    msg7086  
       2021-05-05 10:42:15 +08:00   ❤️ 1
    Ruby 的大概这样?

    Dir['Action/*.py'].map{|f| '"' + Pathname.new(f).basename.sub_ext('').to_s + '"'}.join(',')

    如果能接受两边有 [] 的话,直接数组转字符串或者转换成 JSON 都行。
    AndyAO
        5
    AndyAO  
    OP
       2021-05-05 11:01:59 +08:00
    @msg7086 #4

    比起其他 Shell 语言来说,自以为可读性比那几个 Shell 语言强很多,像我这种完全不懂的人也能看明白大概是什么意思。

    能做到这种简洁性和可读性真是太好了!这个比 PowerShell 强

    最近翻看过几本松本行弘的书,感到这个人对于编程语言有着深刻的理解。
    AndyAO
        6
    AndyAO  
    OP
       2021-05-05 11:07:04 +08:00
    @aloxaf #2

    的确很短,但是感觉只会对熟悉 zsh 的人有可读性,毕竟没怎么用英语,都是用的符号。

    楼下的那个 Ruby 应该强很多。
    aloxaf
        7
    aloxaf  
       2021-05-05 11:19:05 +08:00
    @AndyAO pwsh 也能很简洁吧:'"' + ((dir *.py |% BaseName) -join '","') + '"'
    KomiSans
        8
    KomiSans  
       2021-05-05 11:56:12 +08:00
    `
    let co = fs.readdirSync("../Action").filter(x=>x.indexOf(".py")>0).map(single=>single.replace(".py","")).toString();
    `
    Node.JS 好像有点复杂
    ctro15547
        9
    ctro15547  
       2021-05-05 11:57:26 +08:00   ❤️ 1
    import os
    print((lambda x:[i for i in x if i.find('.py') != -1])(os.listdir()))

    有办法弄成一行吗。。。
    AndyAO
        10
    AndyAO  
    OP
       2021-05-05 12:19:32 +08:00
    @aloxaf #7

    按的也是 pwsh,你的写法的启发在于,直接在 path 用通配符,而不是用过滤器参数,问题貌似在于你遗漏了 -File 参数,这就导致如果文件夹名是.py 结尾可能会有错。

    至于使用那种拼接操作,这个虽然更简洁,但是可读性并不好,我之前就是这么写的,后来换了 Join-String 。

    你这个的意义在于,很好的展示了,只要愿意用符号 pwsh 比 zsh 和 bash 在长度方面也不差。
    AndyAO
        11
    AndyAO  
    OP
       2021-05-05 12:21:40 +08:00
    @aloxaf #7

    已改为 ↓

    (dir -File *.ps1).BaseName | Join-String -DoubleQuote -Separator ','
    AndyAO
        12
    AndyAO  
    OP
       2021-05-05 12:26:18 +08:00
    @ctro15547 #9 是不是一行不关键,主要是简洁方便就行
    AlisaDestiny
        13
    AlisaDestiny  
       2021-05-05 13:14:14 +08:00   ❤️ 2
    python3 -c "import os;print([x.split('.')[0] for x in os.listdir('.') if x.endswith('.py')])"
    O5oz6z3
        14
    O5oz6z3  
       2021-05-05 13:17:02 +08:00   ❤️ 1
    python3 另外四种写法……
    单引号+文件检测
    ```python
    from pathlib import Path
    print(str([x.stem for x in Path('.').glob('*.py') if x.is_file()])[1:-1])
    ```

    双引号
    ```
    python -c "from pathlib import Path; print(','.join([f'\"{x.stem}\"' for x in Path('.').glob('*.py')]))"
    python -c "from pathlib import Path; print(*[f'\"{x.stem}\"' for x in Path('.').glob('*.py')], sep=',')"
    python -c "from pathlib import Path; from json import dumps; print(dumps([x.stem for x in Path('.').glob('*.py')], ensure_ascii=False)[1:-1])"
    ```
    learningman
        15
    learningman  
       2021-05-05 13:29:46 +08:00 via Android
    @ctro15547 可以,__import__
    no1xsyzy
        16
    no1xsyzy  
       2021-05-05 19:57:04 +08:00
    #!/usr/bin/env racket
    #lang rash
    (require rash/demo/setup)
    ls |>> string-split _ "\n" =filter= string-suffix? _ ".py" =map= string-append "\"" _ "\"" |> string-join _ "," |> display

    除了每个 string 相关函数都带个 string- 前缀外挺简短的。
    zbinlin
        17
    zbinlin  
       2021-05-05 22:36:02 +08:00
    bash shell 的这个还不简单吗?

    ls -mQ *.py 2>/dev/null
    TunkShif
        18
    TunkShif  
       2021-05-06 11:51:58 +08:00 via Android
    ```elixir
    # 使用 comprehension
    for file <- File.ls!("scripts"), String.end_with?(file, ".py") do file end |> Enum.join(",")

    # 无脑用管道符
    File.ls!("scripts") |> Enum.filter(&(String.ends_with?(&1, ".py"))) |> Enum.join(",")
    ```
    AoEiuV020
        19
    AoEiuV020  
       2021-05-06 12:12:08 +08:00
    shell, 本来以为很简单,没想到写出来还是用了 3 个管道,讲道理还是编程语言直接遍历更好,
    ls *.py|sed 's/\(.*\).py/"\1"/'|tr -t '\n' ','|sed 's/,$//'
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2826 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:59 · PVG 10:59 · LAX 18:59 · JFK 21:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.