I'm building a shell and I have a user input command.
I want to glob the command if it contains a * or a ?
Because I am using the subprocess module, my commands are being stored in a list. With piping, it can become a list of lists.
Thus, my data is potentially coming in as [["first", "set", "of", "commands"],[["second", "set", "of", "commands"]]
Now, let us suppose that there is an * in one of the commands and I need to glob.
the python glob module returns a list. Because of this, if my user input ls *.py in a directory with 3 python files, globing would return a nested loop ["ls, ["1.py", "2.py", "3.py"]] but I need it to return a flat list like this: ["ls", "1.py", "2.py", "3.py"]
I can make this work with the following code,
# 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
now, while it works, it is just ugly as sin and I feel like there should be a better way to do it.
Ideally, I want to use a list comprehension but I'm not sure it's even possible to return what I need from the comprehension.
It would be great if I could do something like:
# 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
]
obviously, this throws a syntax error. Is it even possible to achieve this using a list comprehension? And if it is, what am I missing?