Code Golf Techniques in Python
In regular golf, players try to complete a hole in as few strokes of the club as possible. In code golf, programmers try to complete a hole (some sort of coding challenge) in as few key strokes as possible. In other words, the challenge is the write the shortest possible computer program – measured in either characters or bytes – that performs some task in an agreed upon language.
Consider the following three python programs:
a = 1
b = 1
for i in range(50):
print(a)
temp = b
b = a + b
a = temp
a,b=1,1
for i in range(50):
print(a)
a,b=b,a+b
a=b=1
exec('print(a);a,b=b,a+b;'*50)
They all produce the same output, namely the first 50 terms of the Fibonacci sequence. This is a classic code golf hole. The solutions are increasingly compressed (aka “golfed”), with the third solution seemingly approaching a lower bound1 for this task at only 36 bytes. As a general rule, the more heavily golfed your solution, the more incomprehensible it becomes.
Code golf produces some very silly looking programs but can be a great way to learn the nuances of a language. Here are some of the most useful techniques I have employed over the years.
Techniques
Removing Whitespace
if a < b or 6 % foo() == 2:
return bar()
if a<b or 6%foo()==2:return bar()
Whitespace can be removed in a surprising number of places. In general, spaces around symbolic operators can be removed. Spaces after numbers can also be removed (except for when followed by e
or E
). Always try to minimize indentation and remember to use a single tabbing character instead of multiple spaces. 2
Unpacking in Assignments
one = "1"
two = "2"
three = "3"
one, two, three = "123"
Chained Assignments
a, b, c = 1, 1, 1
a = b = c = 1
Chained Comparisons
if a < b and b > c and c >= 7:
foo()
if a < b > c >= 7:
foo()
Works for any combination of the built-in comparison operators: ">" | "<" | "==" | ">=" | "<=" | "!=" | "is" ["not"] | ["not"] "in"
Simultaneous Equality Checking
if a == 4 and b == 2:
bar()
if (a,b) == (4,2):
bar()
Shorter Ternaries
"profit" if revenue > expense else "loss"
("loss", "profit")[revenue > expense]
Short-Circuiting for Control Flow
if len(factors(n)) == 2:
print("prime!")
len(factors(n)) == 2 or print("prime!")
or
will only evaluate the second argument if the first isFalse
and
will only evaluate the second argument if the first isTrue
This technique makes use of the fact that python expressions (e.g. function calls) can have “side-effects” apart from their return value.
Aliasing Built-in Functions
for x in range(10):
for y in range(x, 15):
print(z**2 for z in range(x, y))
r = range
for x in r(10):
for y in r(x, 15):
print(z**2 for z in r(x, y))
Abusing exec
and eval
for _ in range(42):
bar()
exec("bar();" * 42)
Using exec
and eval
allows us to manipulate source code as strings, which opens up a world of possibilities.
Collapsing Nested Loops
for y in range(height):
for x in range(width):
bazz(x, y)
for i in range(width*height):
bazz(i % width, i / height)
This can be extended to three or even more nested loops, but in these cases it often becomes cheaper to import itertools.product
.
Avoiding not
if not condition:
foo()
if 1-condition:
foo()
Abusing Bitwise Operators
if (a and b) or c:
bar()
if (a & b) | c:
bar()
Other useful bitwise operators include ~n
which is equivalent to -(n+1)
, and a^b
which is equivalent to the exclusive-or (a or b) and not (a and b)
.
Avoiding append
and extend
my_list = [2, 3, 5, 7]
my_list.append(11)
my_list.extend([13, 17, 19])
my_list = [2, 3, 5, 7]
my_list += [11]
my_list += [13, 17, 19]
Shorter Set Containment
my_set = {2, 3, 5, 7}
if 8 in my_set:
print("prime!")
my_set = {2, 3, 5, 7}
if {8}&my_set:
print("prime!")
Printing Tricks
my_list = ["x", "y", "z"]
print(" ".join(my_list))
for x in ("abc", "123", "xyz", "456"):
print(x)
print("abc", end="") # no newline
my_list = ["x", "y", "z"]
print(*my_list)
for i in range(4):
print("a1x4b2y5c3z6"[::i])
print(end="abc") # no newline
Where to Play Code Golf?
Some of the best websites for finding code golf holes:
Let me know of any other good techniques that I missed. Happy golfing!