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 is False
  • and will only evaluate the second argument if the first is True

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!