我正在构建一个 shell,并且我有一个用户输入命令。
如果命令包含 *
或 ?
因为我正在使用 subprocess
模块,所以我的命令存储在一个列表中。通过管道,它可以成为列表的列表。
因此,我的数据可能作为 [["first", "set", "of", "commands"],[["second", "set", "of", "commands""]]
现在,让我们假设其中一个命令中有一个 *
,我需要 glob。
python glob
模块返回一个列表。因此,如果我的用户在包含 3 个 python 文件的目录中输入 ls *.py
,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
]
显然,这会引发语法错误。甚至可以使用列表理解来实现这一点吗?如果是,我错过了什么?
最佳答案
这里最优雅的解决方案是简单地构建一个新列表而不是乱用索引。
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 循环。
关于python - 如何从列表理解中返回字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63184925/