Here is the original code:
import site;
import re
for i in site.getsitepackages():
package = re.search("^/usr/local/lib/.*/dist-packages$", i)
if package is None:
continue
print(package.string)
Output:
/usr/local/lib/python3.8/dist-packages
Here is the one line code:
import site; import re; for i in site.getsitepackages(): package = re.search("^/usr/local/lib/.*/dist-packages$", i); if package is None: continue; print(package.string)
Output:
File "/tmp/ipykernel_2984/3719293883.py", line 1
import site; import re; for i in site.getsitepackages(): package = re.search("^/usr/local/lib/.*/dist-packages$", i); if package is None: continue; print(package.string)
^
SyntaxError: invalid syntax
I want to convert the above multiple lines into one line, and then run it in the bash command line:
python3 -c "<one line python code>"
CodePudding user response:
Why a single line? It will impact readability.
Just use a heredoc:
python3 <<!
import site;
import re
for i in site.getsitepackages():
package = re.search("^/usr/local/lib/.*/dist-packages$", i)
if package is None:
continue
print(package.string)
!
CodePudding user response:
While it is possible to join some python lines together with a semicolon, you can not do that with loops. See this answer
Because the Python grammar disallows it. See the documentation:
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Semicolons can only be used to separate simple statements (not >compound statements like for). And, really, there's almost no >reason to ever use them even for that. Just use separate lines. >ython isn't designed to make it convenient to jam lots of code >onto one line.
However, to run a loop with python -c
you can just run it over multiple lines. For example, the command below prints out the numbers 0 - 9 on seperate lines:
python -c 'while i in range(10):
print(i)
'
CodePudding user response:
The issue is with the for
command, which is not allowed to be used with the ;
operator or with more than one :
operator in Python.
There are a few ways you could massage this sort of thing into working, but the simplest is with a clever use of list comprehensions.
import re, site; [print(package.string) for i in site.getsitepackages() if (package := re.search("^/usr/local/lib/.*/dist-packages$", i))]
Which you can execute from bash
like:
pyhton3 -c 'import re, site; [print(package.string) for i in site.getsitepackages() if (package := re.search("^/usr/local/lib/.*/dist-packages$", i))]'
The above takes advantage of the fact that print(package.string)
only gets executed when the if
is true. It also takes advantage of the :=
"walrus" in-place assignment operator, which works like the normal =
except that you can use it inside a formula or list comprehension.
You can also use a here doc, if this is in a fully-fledged bash
script.
python3 <<!
import re
import site
for i in site.getsitepackages():
if package := re.search("^/usr/local/lib/.*/dist-packages$", i):
print(package.string)
!
And finally you can use in-line newlines from bash:
python -c $'import re, site\nfor i in site.getsitepackages():\n if package := re.search("^/usr/local/lib/.*/dist-packages$", i):\n print(package.string)'
When you place a $
in front of a single-quoted string, then bash
will expand backslash escaped newlines and other backslash escapes. (Be careful when combining this with regex though!)