Tips for golfing in Python
If you have any tips for golfing in Python, add them as answers to this post.
Use the unpacking `` instead o …
3y ago
If you print some string `s` w …
3y ago
Reorder expressions in order t …
3y ago
Combine conditionals Python …
3y ago
Replace `n+1` with `-n` and `n …
3y ago
Replace if/else expressions by …
3y ago
Use `a+=[b]` instead of `a.app …
3y ago
` == and` If you want to ch …
3y ago
Combine loops Suppose you h …
3y ago
Replace `range()` if $n …
3y ago
Assign `float`s while leaving …
3y ago
Renaming functions A funny, …
3y ago
Use `lambda`s instead of funct …
3y ago
`import` You can import som …
3y ago
Replace print loops by list un …
3y ago
Replace `for` loops with strin …
3y ago
If you have a loop or `if`, yo …
3y ago
`| == or` This bitwise oper …
3y ago
18 answers
Use lambda
s instead of functions
At most times, lambda
s tend to make smaller code, which is helpful in golfing. Assigning a lambda
is easy, just do:
lambda f:whatever
There are many answers that uses this strategy (I don't use it). Here are some examples:
0 comment threads
If you print some string s
without a newline character at the end, instead of
print(s,end="")
write
print(end=s)
to save two bytes.
Note that this only works for strings, not for other types.
Note also that if you print more than one string, then the end=
part will also prevent inserting spaces between them; to avoid getting those extra spaces, in that case you'll need to use string concatenation (string addition) instead.
For example, instead of
print(s,t,end="")
use
print(end=s+t)
Again, this only works if all arguments are strings.
0 comment threads
Use the unpacking *
instead of list
If you want to convert an iterator/generator into a list, use the *
operator instead of using the list
function, e.g.
Instead of
list(iterable)
Use
[*iterable]
0 comment threads
Combine conditionals
Python has its fair share of comparison operators and can actually be used in a single conditional. For example:
x == 2 and y == 2
can be:
x==y==2
Used on Make $2 + 2 = 5$.
@celtschk also mentions that different operators can also enter a single conditional, as long as an order is applied.
For example:
a < b and b > c
Can be rewritten as:
a<b>c
1 comment thread
Reorder expressions in order to save whitespace
Consider the following code:
if c=='U':c='X'
The space between if
and c
obviously cannot be removed, as that would merge them to the identifier ifc
. However by reversing the order of the arguments to ==
, the space becomes removable:
if'U'==c:c='X'
As user noted in the comments, another place where whitespace can be saved is between a number and a following keyword. For example, in
if 2+x in{a,b,c}:x=0
the space between x
and in
cannot be simply removed. However reordering the sum allows to remove it anyway:
if x+2in{a,b,c}:x=0
1 comment thread
Use a+=[b]
instead of a.append(b)
The title says it all.
a=[];b=10;print(a)
a+=[b];print(a)
0 comment threads
Renaming functions
A funny, cool, and useful trick. If you have to write a single function multiple times (usually range()
on for
loops), then you can simply assign a variable by the function's name, no parentheses. An example assignment is:
r=range
Thing is, this can only apply to save bytes if the function is either long enough to save more and the times it was used. If not even twice, it's unnecessary. There're rarely any answers using this format for this exact reason. There aren't a lot of times where you'd need to keep adding the same function on the program when it comes to golfing.
0 comment threads
Replace if/else expressions by array subscripts
Consider the statement
a=b if x<y else c
You can get rid of the expensive keywords by using the implicit conversion of boolean values to integer and array indexing:
a=[b,c][x<y]
Note however that here b
and c
are evaluated unconditionally, therefore this replacement doesn't work if b or c are expressions with side effects.
0 comment threads
import*
You can import some libraries and if you find yourself using:
from lib import *
Remove the space between import
and *
, because it works for whatever reason.
0 comment threads
Replace range()
if $n < 4$
If you're using a for
loop, you're probably using range()
for the list count. You can actually replace it if the number inside range()
is less than 4. Why? Examine the lengths on the code:
0,1
0,1,2
0,1,2,3
0,1,2,3,4
range(n)
range()
takes more bytes than the list from 0 to 3.
for i in 0,1,2,3:print(i)
0 comment threads
Replace n+1
with -~n
and n-1
with ~-n
For integers, n+1
and ~-n
have the same value, as have n-1
and -~n
.
While the expressions themselves have the same lengths, the replacements often allow to save space by allowing either to remove whitespace or to omit parentheses due to different precedence.
For example,
a=12*(n+1)
can be replaced by
a=12*-~n
0 comment threads
Replace for
loops with string multiplication
Let's say we have:
for i in range(6):print(end="#")
This basically outputs #
6 times, which is self-explanatory in the code itself. Perhaps we can shorten it with string multiplication:
print(end="#"*6)
Same result, lesser bytes.
0 comment threads
Replace print loops by list unpacking
If you want to print elements of a list one per line, the straightforward way to do it is a loop:
for i in l:print(i)
But this can be shortened using list unpacking:
print(*l,sep="\n")
Note that despite the extra sep
this is still one character shorter.
0 comment threads
If you have a loop or if
, you can save two or more characters (depending on the current indentation level and the number of statements in the body) by putting it right after the colon:
For example, assume you have this loop with 33 characters:
for x in a:
do_something_with(x)
Since you've got just one statement, you can delete the newline character and the following indentation space, in order to get 31 characters:
for x in a:do_something_with(x)
If the body has more than one statement, those can be separated with semicolon. For example
if (condition):
do_something()
do_more()
becomes
if condition:do_something();do_more()
Thanks to @Moshi for pointing out that it also works with several statements.
Assign float
s while leaving out zeroes
Python allows such strange assignment.
You can save bytes by removing the number preceding .
if it's only 0
:
i=.5
print(i)
The same goes for succeeding digits, if the decimal part of the float
is 0
:
i=5.
print(i)
You can't assign something with only .
though, which is unfortunate.
0 comment threads
* == and
If you want to check if two booleans or integers and want to check if both of them are true
in an if
statement, then you can leave out and
to replace it with *
:
x=2;y=3
if x and y:print("Yes")
if x*y:print("Yes")
0 comment threads
Combine loops
Suppose you have a for
loop in another, maybe a couple of times, and nothing else inside of the outer for
loops (except for the first for
loop since anything outside won't be involved at all). It's probably a range()
problem again.
If you're doing something like this:
x=10;y=15
for i in range(x):
for j in range(y):
print(i,"-",j)
You can simply set the loop as one:
x=10;y=15
for i in range(x*y):print(i//y,"-",i%y)
Golfing 16 bytes in total. You can do this with more loops, but this is what's functional for now.
0 comment threads
| == or
This bitwise operator can sometimes be used as the replacement for or
.
a=-2;b=3
if(a>0)|(b>0):print(a+b)
0 comment threads