Q&A

Tips for golfing in Python

+1
−0

If you have any tips for golfing in Python, add them as answers to this post.

Why does this post require moderator attention?
Why should this post be closed?

+3
−0

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.

print(s,t,end="")


use

print(end=s+t)


Again, this only works if all arguments are strings.

Why does this post require moderator attention?

+3
−0

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.

list(iterable)


Use

[*iterable]

Why does this post require moderator attention?

+2
−0

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

Why does this post require moderator attention?

+2
−0

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

Why does this post require moderator attention?

+1
−0

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

Why does this post require moderator attention?

+1
−0

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.

Why does this post require moderator attention?

+1
−0

* == 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")


Try it online!

Why does this post require moderator attention?

+1
−0

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.

Why does this post require moderator attention?

+1
−0

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.

Why does this post require moderator attention?

+1
−0

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.

Why does this post require moderator attention?

+1
−0

Use lambdas instead of functions

At most times, lambdas 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:

Why does this post require moderator attention?

+1
−0

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)


Try it online!

You can simply set the loop as one:

x=10;y=15
for i in range(x*y):print(i//y,"-",i%y)


Try it online!

Golfing 16 bytes in total. You can do this with more loops, but this is what's functional for now.

Why does this post require moderator attention?

+1
−0

Use a+=[b] instead of a.append(b)

The title says it all.

a=[];b=10;print(a)
a+=[b];print(a)


Try it online!

Why does this post require moderator attention?

+1
−0

Assign floats 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)


Try it online!

The same goes for succeeding digits, if the decimal part of the float is 0:

i=5.
print(i)


Try it online!

You can't assign something with only . though, which is unfortunate.

Why does this post require moderator attention?

+1
−0

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.

Why does this post require moderator attention?

+1
−0

Replace for loops with string multiplication

Let's say we have:

for i in range(6):print(end="#")


Try it online!

This basically outputs # 6 times, which is self-explanatory in the code itself. Perhaps we can shorten it with string multiplication:

print(end="#"*6)


Try it online!

Same result, lesser bytes.

Why does this post require moderator attention?

+1
−0

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)


Try it online!

Why does this post require moderator attention?

+0
−0

| == 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)


Try it online!

Why does this post require moderator attention?