Is it possible to write one-liners in Python? [closed] - python

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I was going through the code golf question here on Stack Overflow and saw many Perl one-liner solutions.
Is something like that possible in Python?

python -c 'print("Yes.")'

It's possible to write one liners in Python but it's awkward (Python encourages well indented code which is somewhat at odds with the "one-liner" concept). It's a bit easier in Python 3 because print() is a function and not a statement. Here's one:
python -c "fact = lambda x: x * fact(x-1) if x > 1 else 1; print(fact(5))"
Here's how you could write a grep like function (this example prints lines from input containing "foo"):
python -c "for s in __import__('fileinput').input(): __import__('sys').stdout.write(s) if 'foo' in s else None"

I end up wanting to do this fairly often when doing stuff from the shell. It doesn't end up being more compact, and in many cases it's easier to just write a multi-line shell command than to write everything as a lambda. You pretty much can't use any Python statement that ends with a colon. So you end up having to
write any for-like code as a genexp or list comprehension. I Do this anyway for most stuff, but it's annoying to have to import sys and push everything to sys.stdout.writelines in cases where you could otherwise just
for tree in forest:
print tree
write lambdas instead of function definitions. This is often workable and has the useful side effect of forcing you to write very directed functions that really only do one thing. However, it's not particularly convenient, and doesn't work for anything that mutates a value (e.g., dict.update) and then returns some element.
Do not bother doing things properly with context managers
Do not do any exception handling.
Use a dictionary of lambdas instead of any if/else sections.
Use type(name, bases, dict) to declare any classes. This is pretty fun but only works if you happen to be declaring a class whose methods can all be expressed as lambdas.
So for some things it works out but generally it's a big hassle, because you end up having to use a functional style that Python doesn't really support. Most of the time I just write multiline shell commands like
python -c $'
import some_module
for v in some_module.whatever():
print "Whatever: \'{0}\'".format(v)
'
The $' is a bash quoting syntax, an alternative to its '...' and "..." quoting constructs. It's useful, because it works like '...', but let’s you escape contained ' characters with \'. You can also embed newlines, so the above code could also be written as python -c $'import some_module\nfor v in some_module.whatever():\n print "Whatever: \'{0}\'".format(v)'. However, this is something of an acquired taste.
One annoying thing about writing multiline commands in bash is that HOME and END go to the beginning of the command rather than the beginning of the line. There may be a better way to do this, but I usually just scan back and forth by holding down CTRL and the left/right arrow keys. Some Emacs user could probably set me straight here, since that's where bash's normal key bindings come from.
If you want to insert a line break while editing a multiline command, you can do this with ^V-^J. That will put in a line break in such a way that you can still scan back to the previous lines, rather than using the
$ first line of the command
> second line
> third line
setup that you get otherwise, where you can't get back to the previous lines.
The trick with ^V-^J works in IPython too, making it useful for editing class or function definitions. It may also work in the basic Python REPL (probably); I just don't know, because I nearly always use IPython.

In Bourne shell you can use something called heredoc to get around Python's dependency on indents:
python << 'EOF'
> for i in range(3):
> print i
> EOF
0
1
2

A really nice Python one-liner (as in "quite useful"):
python -c 'import SimpleHTTPServer as foo; foo.test()' 23433
It creates an instant basic web server in the current directory. (I was just introduced to this today, and it is very handy.)

Here is my trick to run multiple statements:
[stmt1, stmt2, expr1][2]
if requires lazy evaluation: [lambda(): stmt1; lambda(): stmt2][not not boolExpr]()

exec("if 6 * 9 == int('42', 13):\n\tprint('Yes!')")
With this approach, every Python program can be written as a one-liner :)

Yes, actually it is very common. I use one-liners when I need to write quick code. It just depends on what you want to do. Here is a small line I just used this evening. It is the creation of a Tkinter button in a single line.
a = Button(root, text="Button", command=com1).pack()

Related

How to achieve "neat" line breaking for several arguments in Python + VSCode?

I am new to Python and I couldn't find the answer for this precise question elsewhere. Let's say one is using a Python function with several inputs. Ideally, for readability, I would like to write code as
my_variable = my_function (arg1 = bla_bla_bla_1,
arg2 = bla_bla_bla_2,
arg3 = bla_bla_bla_3)
This is very easy on RStudio with, for example, just using Enter. I am using Python on Visual Studio Code but I can't find a way to do it. Ideally, it would look like this:
But of course such code won't run since Enter and Tab or Space will break it. Is there anyway to achieve this? I see that this is different than, let's say, code wrapping. But I don't know the name of this property/way of writing code. Thanks in advance!
Using \ should do the trick like so:
a = [5,4,6,\
4,5,6]
Python is quite prescriptive about style. The spec is known as PEP-8 https://www.python.org/dev/peps/pep-0008/
You can install a “linter” in VSCode which will alert you to general style breaches. See https://code.visualstudio.com/docs/python/linting
For your specific question, I think this is the prescribed way.
variable = my_function(
arg1 = bla_bla_bla_1,
arg2 = bla_bla_bla_2,
arg3 = bla_bla_bla_3,
)
You might disagree, but python doesn’t leave much room for your opinion on this 😀. This can be frustrating at first, but when embraced allows you to focus on coding instead of style; and, crucially, a standard style ensures readability when code is shared by multiple python developers.

Python REPL: issuing commands in advance to execute after block

This is a bit of an odd question; it came up in the context of a tool that exposes a Python API, which we spend a lot of time querying interactively from the REPL. The particular idiom causing issues is something like this:
for var in slow_generator_of_giant_list():
stats = update(stats, var)
print stats
To enter this at the REPL, I can type this:
>>> for var in slow_generator_of_giant_list():
... stats = update(stats, var)
...
If I now attempt to type the print, I get a syntax error due to improper indentation. (Or else I put the print inside the loop and do it on every iteration.)
But if I hit enter to go to the next line, the loop runs immediately, and I have to wait for it to finish, or type the print command in the face of possible output coming at me, etc.
Obviously I can define a function containing the above, and it might be worth saving into a file anyway, but in the general case we're constructing these on the fly, and it would be nice to have a way to "schedule" a command to run after the end of a loop from the REPL. In a language with block delimiters, I could of course put it after the ending delimiter (and any necessary statement separator). But my coworkers and I were stumped trying to do something similar here.
Is there perhaps an ugly abuse of Pythonic syntax that will do the trick that my coworkers and I couldn't think of? Or a recommended way to avoid the problem while still making it easy to throw together ad hoc interactive queries?
Thanks for any pointers.
Not beautiful, but this should work:
>>> mygen = slow_generator_of_giant_list()
>>> try:
... while True: stats = update(stats, mygen.next())
... except StopIteration:
... print stats
...
I would just say that you would find it easier just to not use the interactive shell for this.
It's not much effort to save a file and run it. You only have to keep it around for as long as you use it.
I actually have found this answering on SO. I keep a file open in my text editor with a terminal in the right directory, and just use it as a scratchpad for mocking up answers in.

Given the my code is open source and I'm running on a server, and I accept nearly-raw code, what's the worst that can happen to me?

I'm looking at several cases where it would be far, far, far easier to accept nearly-raw code. So,
What's the worst you can do with an expression if you can't lambda, and how?
What's the worst you can do with executed code if you can't use import and how?
(can't use X == string is scanned for X)
Also, B is unecessary if someone can think of such an expr that given d = {key:value,...}:
expr.format(key) == d[key]
Without changing the way the format looks.
The worst you can do with an expression is on the order of
__import__('os').system('rm -rf /')
if the server process is running as root. Otherwise, you can fill up memory and crash the process with
2**2**1024
or bring the server to a grinding halt by executing a shell fork bomb:
__import__('os').system(':(){ :|:& };:')
or execute a temporary (but destructive enough) fork bomb in Python itself:
[__import__('os').fork() for i in xrange(2**64) for x in range(i)]
Scanning for __import__ won't help, since there's an infinite number of ways to get to it, including
eval(''.join(['__', 'im', 'po', 'rt', '__']))
getattr(__builtins__, '__imp' + 'ort__')
getattr(globals()['__built' 'ins__'], '__imp' + 'ort__')
Note that the eval and exec functions can also be used to create any of the above in an indirect way. If you want safe expression evaluation on a server, use ast.literal_eval.
Arbitrary Python code?
Opening, reading, writing, creating files on the partition. Including filling up all the disk space.
Infinite loops that put load on the CPU.
Allocating all the memory.
Doing things that are in pure Python modules without importing them by copy/pasting their code into the expression (messing with built in Python internals and probably finding a way to access files, execute them or import modules).
...
No amount of whitelisting or blacklisting is going to keep people from getting to dangerous parts of Python. You mention running in a sandbox where "open" is not defined, for example. But I can do this to get it:
real_open = getattr(os, "open")
and if you say I won't have os, then I can do:
real_open = getattr(sys.modules['os'], "open")
or
real_open = random.__builtins__['open']
etc, etc, etc. Everything is connected, and the real power is in there somewhere. Bad guys will find it.

Printing Variable names and contents as debugging tool; looking for emacs/Python shortcut

I find myself adding debugging "print" statements quite often -- stuff like this:
print("a_variable_name: %s" % a_variable_name)
How do you all do that? Am I being neurotic in trying to find a way to optimize this? I may be working on a function and put in a half-dozen or so of those lines, figure out why it's not working, and then cut them out again.
Have you developed an efficient way of doing that?
I'm coding Python in Emacs.
Sometimes a debugger is great, but sometimes using print statements is quicker, and easier to setup and use repeatedly.
This may only be suitable for debugging with CPython (since not all Pythons implement inspect.currentframe and inspect.getouterframes), but I find this useful for cutting down on typing:
In utils_debug.py:
import inspect
def pv(name):
record=inspect.getouterframes(inspect.currentframe())[1]
frame=record[0]
val=eval(name,frame.f_globals,frame.f_locals)
print('{0}: {1}'.format(name, val))
Then in your script.py:
from utils_debug import pv
With this setup, you can replace
print("a_variable_name: %s' % a_variable_name)
with
pv('a_variable_name')
Note that the argument to pv should be the string (variable name, or expression), not the value itself.
To remove these lines using Emacs, you could
C-x ( # start keyboard macro
C-s pv('
C-a
C-k # change this to M-; if you just want to comment out the pv call
C-x ) # end keyboard macro
Then you can call the macro once with C-x e
or a thousand times with C-u 1000 C-x e
Of course, you have to be careful that you do indeed want to remove all lines containing pv(' .
Don't do that. Use a decent debugger instead. The easiest way to do that is to use IPython and either to wait for an exception (the debugger will set off automatically), or to provoke one by running an illegal statement (e.g. 1/0) at the part of the code that you wish to inspect.
I came up with this:
Python string interpolation implementation
I'm just testing it and its proving handy for me while debugging.

Can you access registers from python functions in vim

It seems vims python sripting is designed to edit buffer and files rather than work nicely with vims registers. You can use some of the vim packages commands to get access to the registers but its not pretty.
My solution for creating a vim function using python that uses a register
is something like this.
function printUnnamedRegister()
python <<EOF
print vim.eval('##')
EOF
endfunction
Setting registers may also be possible using something like
function setUnnamedRegsiter()
python <<EOF
s = "Some \"crazy\" string\nwith interesting characters"
vim.command('let ##="%s"' % myescapefn(s) )
EOF
endfunction
However this feels a bit cumbersome and I'm not sure exactly what myescapefn should be.
So I've never been able to get the setting version to work properly.
So if there's a way to do something more like
function printUnnamedRegister()
python <<EOF
print vim.getRegister('#')
EOF
endfunction
function setUnnamedRegsiter()
python <<EOF
s = "Some \"crazy\" string\nwith interesting characters"
vim.setRegister('#',s)
EOF
endfunction
Or even a nice version of myescapefn I could use then that would be very handy.
UPDATE:
Based on the solution by ZyX I'm using this piece of python
def setRegister(reg, value):
vim.command( "let #%s='%s'" % (reg, value.replace("'","''") ) )
If you use single quotes everything you need is to replace every occurence of single quote with two single quotes.
Something like that:
python import vim, re
python def senclose(str): return "'"+re.sub(re.compile("'"), "''", str)+"'"
python vim.command("let #r="+senclose("string with single 'quotes'"))
Update: this method relies heavily on an (undocumented) feature of the difference between
let abc='string
with newline'
and
execute "let abc='string\nwith newline'"
: while the first fails the second succeeds (and it is not the single example of differences between newline handling in :execute and plain files). On the other hand, eval() is somewhat more expected to handle this since string("string\nwith newline") returns exactly the same thing senclose does, so I write this things now only using vim.eval:
python senclose = lambda str: "'"+str.replace("'", "''")+"'"
python vim.eval("setreg('#r', {0})".format(senclose("string with single 'quotes'")))

Categories

Resources