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

2021-05-05 09:52:26 +08:00
 AndyAO

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

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

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

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

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

"$PSScriptRoot\Action" | dir -File -Filter '*.ps1'|% BaseName | Join-String -DoubleQuote -Separator ','
1913 次点击
所在节点    Python
19 条回复
FH0
2021-05-05 10:04:13 +08:00
```bash
echo -e "A.py\nB.py\nC.py\nD.py" | awk -F '.py' '{printf "\"" $1 "\","}' | sed 's|,$||'
```
aloxaf
2021-05-05 10:31:45 +08:00
```zsh
echo \"${(j:",":)${(A)=:-$(print *.py(:r))}}\"
```

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

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

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

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

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

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

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

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

楼下的那个 Ruby 应该强很多。
aloxaf
2021-05-05 11:19:05 +08:00
@AndyAO pwsh 也能很简洁吧:'"' + ((dir *.py |% BaseName) -join '","') + '"'
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
2021-05-05 11:57:26 +08:00
import os
print((lambda x:[i for i in x if i.find('.py') != -1])(os.listdir()))

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

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

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

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

已改为 ↓

(dir -File *.ps1).BaseName | Join-String -DoubleQuote -Separator ','
AndyAO
2021-05-05 12:26:18 +08:00
@ctro15547 #9 是不是一行不关键,主要是简洁方便就行
AlisaDestiny
2021-05-05 13:14:14 +08:00
python3 -c "import os;print([x.split('.')[0] for x in os.listdir('.') if x.endswith('.py')])"
O5oz6z3
2021-05-05 13:17:02 +08:00
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
2021-05-05 13:29:46 +08:00
@ctro15547 可以,__import__
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
2021-05-05 22:36:02 +08:00
bash shell 的这个还不简单吗?

ls -mQ *.py 2>/dev/null
TunkShif
2021-05-06 11:51:58 +08:00
```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
2021-05-06 12:12:08 +08:00
shell, 本来以为很简单,没想到写出来还是用了 3 个管道,讲道理还是编程语言直接遍历更好,
ls *.py|sed 's/\(.*\).py/"\1"/'|tr -t '\n' ','|sed 's/,$//'

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774944

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX