'How to write for loop with condition in one line
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>"
Solution 1:[1]
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)
!
Solution 2:[2]
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)
'
Solution 3:[3]
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!)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Diego Torres Milano |
| Solution 2 | joshmeranda |
| Solution 3 | Pi Marillion |
