# Tips for golfing in Python

What general tips do you have for golfing in Python? I'm looking for ideas which can be applied to code-golf problems and which are also at least somewhat specific to Python (e.g. "remove comments" is not an answer).

• Use Python 2 for golfing not 3 Aug 9 '17 at 15:04
• @Chris_Rands That simply does not universally hold, as there are cases in which Python 3 allows for shorter submissions. Jul 15 '18 at 14:36
• @JonathanFrech Especially the new := operator in 3.8 Mar 17 '19 at 17:31
• Feb 2 at 11:54

# The best way to check whether is a number even or not

Usually you do it this way (6 bytes):

n%2==0


But you can reduce it to 5 bytes:

n%2<1


And even 4 bytes:

~n&1


Bonus tip: when you use if you can ignore spacebetween if and ~n&1 this way:

if~n&1:


Be aware of all, any and map:

if isdigit(a) and isdigit(b) and isdigit(c)
if all(map(isdigit,[a,b,c]))

• filter(function, iterable) returns a list of all the elements of iterable for which function is a True-y value and a non-empty list is True-y, so this can be shortened further to if filter(isdigit,[a,b,c]) Apr 16 '14 at 8:33
• Over a year later, I'm reading this thread again and I'm embarrassed about my previous comment. if filter(isdigit,[a,b,c]) is not equivalent to the code in the answer; but it would be if @moose used isdigit(a) or... and if any(.... Apr 21 '15 at 13:36

If you need to import a lot of modules you can reassign __import__ to something shorter, this also has the advantage of being able to name imports anything you want.

i=__import__;s=i('string');x=i('itertools');

• I've rarely found this to be actually useful. Generally import string,itertools, import string,itertools as M, from itertools import* and other variants tend to be shorter... Jul 25 '15 at 9:05
• s,i=map(__import__,['string','itertools']) is shorter than your example, but still longer than import string as s,itertools as i Jul 12 '17 at 14:44

Abusing try/except blocks can sometimes save characters, especially for exiting out of nested loops or list comprehensions. This:

for c in s:
for i in l:
q=ord(c)==i
if q:print i,c;break
if q:break


... can become this, saving 3 characters:

try:
for c in s:
for i in l:
if ord(c)==i:print i,c;1/0
except:0


... which in this particular instance can be compressed even further using list comprehensions:

try:[1/(ord(c)-i)for c in s for i in l]
except:print i,c


For an example, see e.g. https://codegolf.stackexchange.com/a/36492/16766.

# Alternatives to builtin string functions

### str.capitalize for single words

Use str.title instead for single words. The difference between the two functions is that capitalize only capitalises the first word, while title capitalises all words:

>>> "the quick brown fox".capitalize()
'The quick brown fox'
>>> "the quick brown fox".title()
'The Quick Brown Fox'


### str.index

str.find is almost always better, and even returns -1 if the substring is not present rather than throwing an exception.

### str.startswith

See this tip by @xnor.

### str.splitlines

str.split is shorter:

s.splitlines()
s.split('\n')


However, str.splitlines may be useful if you need to preserve trailing newlines, which can be done by passing 1 as the keepends argument.

## Dictionary defaults as entries

Say you have an dictionary literal, which I'll denote {...}, and you want to get the value for a key k, with a default of d if k is missing.

You can save two bytes by prepending an entry rather than using get

{k:d,...}[k]
{...}.get(k,d)


Because later entries override earlier ones of the same key, the entry k:d gets overwritten if it appears in the dict, but remains if key k isn't present.

Note that this required writing k twice, which is fine for a variable, but poor when k is an expression.

## Find the n'th number meeting a condition

Many sequence challenges ask you to find the n'th number in a sequence of increasing positive integers. When you have a expression p(i) that checks membership, you can do this with the recursive function:

f=lambda n,i=1:n and-~f(n-p(i),i+1)


Note that expression p(i) must give 0 or 1, not just Falsey or Truthy. The outputs are one-indexed, so say for the sequence of primes, it would give

f(1) = 2
f(2) = 3
...


For 0-indexed outputs, shift the base case

f=lambda n,i=1:n+1and-~f(n-p(i),i+1)


The recursive function f=lambda n,i=1:n and-~f(n-p(i),i+1) works by decrementing the required count n each time it gets a hit, and incrementing the output value each time for each value it checks. It might seem weird to redundantly track i, but it's longer to do:

f=lambda n,i=1:n and f(n-p(i),i+1)or~-i


Also compare the natural list strategy (zero-indexed here)

lambda n:[i for i in range(n*n)if p(i)][n]


(You might need a larger bound than n*n.)

If transforming from list to a tuple or set to a set, list or tuple is needed, as of Python 3.5 you can use the splat operator:

tuple(iterable) -> (*iterable,)  (-3 bytes)
set(iterable)   -> {*iterable}   (-2 bytes)
list(iterable)  -> [*iterable]   (-3 bytes)


If you're doing this as well as appending/prepending, you can do the following for an extra bonus:

iterable+[1]       -> *iterable,1          (-2 bytes, 3 for tuples)
iterable+iter2     -> *iterable,*iterable2 (+1 byte, 0 for tuples, though can combine types)
[1]+iterable+[1]   -> 1,*iterable,1        (-3 bytes, -4 for tuples)
iterable+[1]+iter2 -> *iterable,1,*iter2   (0 bytes, -1 for tuples)


Basically, ,* instead of , gives a +1 byte penalty and , instead of ,[] gives -2 bytes.

This shows [1,*iterable,1] is a golfier way of doing [1]+iterable+[1] by one byte, even when we're not doing any type conversion.

And just for fun, {*{}} is the same length as set() for challenges without letters.

• The last one can also be useful if there is a letter preceding set() (e.g. ...and set() can become ...and{*{}}). Oh, and it can be replaced with {*()} or {*[]} if an empty dict feels unsettling. ;-) Jun 29 '18 at 22:37

## Difference of two parallel expressions

Say you have a challenge to find the difference of some characteristic on two inputs. Your solution has the form lambda a,b:e(b)-e(a), where e is some long expression you've written. Repeating e twice is wasteful, so what do you do?

Here are templates sorted by length. Assume that e stands for a long expression, not one that's already defined as a function. Also assume inputs can be taken in either order.

31 bytes*

lambda*l:eval('e(%s)-'*2%l+'0')


*Requires that e only mentions its variable once. Assumes -e(x) negates the whole expression, otherwise requires parens like -(e(x)) for two more bytes.

34 bytes

f=lambda a,*b:e(a)-(b>()and f(*b))


36 bytes

lambda a,b:d(b)-d(a)
d=lambda x:e(x)


36 bytes

a,b=[e(x)for x in input()]
print b-a


37 bytes

r=0
for x in input():r=e(x)-r
print r


39 bytes

lambda*l:int.__sub__(*[e(x)for x in l])


# Formatting a Matrix

I've seen this code to get a character matrix (2D array) as a string.

'\n'.join(''.join(i)for i in M)


It's shorter to use a map instead:

'\n'.join(map(''.join,M))


If you're printing the result, it's shortest to use a for loop:

print('\n'.join(map(''.join,M)))
for i in M:print(*i,sep='')      # -5 bytes


If you're using Python 2, you can't use the print trick, but you can still use the for loop:

for i in M:print(''.join(i))     # -3 bytes


## Replace not with 1-

In python, the negation operator not wastes bytes, so we have to find a shorter way. Negation can be implemented as subtraction from 1 (obtained from my Keg experiece), which saves 1 byte. (Also, True and False can be alternatively represented as 1 and 0 internally, so this will not matter much.)

Compare this program:

lambda s:not(s[0]+s[-1]).isdigit()


With this program:

lambda s:1-(s[0]+s[-1]).isdigit()


Some straightforward tricks that might help:

and -> *
or -> +


# Using exec to remove repeated print

This is not quite often applicable, but can save some bytes, especially in ASCII art. Take the following code, which prints the flag where n=4.

# 43 bytes                  |  ***
n=input()                   |  **
while~-n:n-=1;print'*'*n    |  *
print'|'                    |  |


Notice that we repeat print twice. We can remove this using exec in the following code, saving 3 bytes.

# 40 bytes
n=input()
exec"'*'*n;n-=1;print"*n+"'|'"


# Printing the elements of a list, with spaces

Suppose we have to print a list as a string with spaces, like square of numbers upto 10. Then,

print(' '.join(str(i**2)for i in range(11))) # 44 chars

print(*(i**2for i in range(11))) # 32 chars


## Combine assignments of reused values with unused for-loop variables

If you need to loop a number of times but you don't care about the iteration variable, you can co-opt the loop to assign a variable.

r=reused;for _ in"_"*n:stuff
r=reused;exec("r;"*n)                          # [note 1]
r=reused;exec"r;"*n                            # [note 1]; Python 2 only
for r in[reused]*n:r

lambda args:((r:=reused)for _ in"_"*n)         # generally needs parentheses
lambda args,r=reused:(r for _ in"_"*n)         # only works with constants
lambda args:(r for r in[reused]*n)


This is generally a more versatile approach for assignment than the := operator or using default arguments of functions, because it supports assigning to attributes .x, subscripts [x], and unpacking with * or ,.

(stuff+(a[0]:=value)for _ in"_"*n)                   # syntax error
(stuff+a[0]for a[0]in[value]*n)                      # works, and shorter!

(stuff+a+b for*a,b in[value]*n)                      # works!


The only pitfall is that scope inside comprehensions is sometimes quite confusing, because the body of the comprehension is compiled as a separate implicit function.

[note 1]: and longer if backslashes/quotes need to be escaped inside the string

This is a bot account operated by pxeger. I'm posting this to get enough reputation to use chat.

• howdy there stranger! welcome to code gol...oh wait nevermind. Jul 20 at 11:44

Sometimes you can use Python's exec-statement combined with string repetition, to shorten loops. Unfortunately, you can't often use this, but when you can you can get rid of a lot of long loop constructs. Additionally, because exec is a statement you can't use it in lambdas, but eval() might work (but eval() is quite restricted in what you can do with it) although it's 2 characters longer.

Here is an example of this technique in use: GCJ 2010 1B-A Codegolf Python Solution

• What kind of restrictions are you thinking about? I don't think Python in itself has any kind of restriction on exec, so you must be referring to problem statements? Jan 28 '11 at 8:43
• @hallvabo, you're right it's eval() I was most likely thinking of. You can't do eval("print 1") because print 1 is a statement. I'll update the post. Jan 28 '11 at 10:23
• As a general rule, this is worth trying when you need to do something n times, but don't care about the index. As soon as you need to initialise a loop variable and increment it, it ends up slightly longer than a for loop Feb 3 '11 at 20:35
• In Python 3 you can do eval("print(1)") since print() is now a function. Apr 20 '14 at 23:02
• In Python 3 you can also do exec("print(1)") since exec() is now a function. May 28 '17 at 5:37

Was somewhat mentioned but I want to expand:

[a,b],[c,d]=[[1,2],[3,4]]


works as well as simple a,b=[1,2]. Another great thing is to use ternary operator (similiar to C-like ?:)

x if x<3 else y


and no one mentioned map. Map will call first function given as first argument on each item from second argument. For example assume that a is a list of strings of integers (from user input for example):

sum(map(int,a))


will make sum of all integers.

• Quoting the OP: Please post one tip per answer. Jun 23 '14 at 13:53
• x if cond else y == cond and x or y. Jul 5 '18 at 9:34

If you rely on data (mostly for kolmogorov-complexity problems), use the built-in zip encoding/decoding and store the data in a file (add +1 for the filename):

open('f','rb').read().decode('zip')


If you have to store the data in the source code, then you need to encode the zip with base64 and do:

"base64literal".decode('base64').decode('zip')


These don't necessarily save characters in all instances, though.

When your program needs to return a value, you might be able to use a yield, saving one character:

def a(b):yield b


However, to print it you'd need to do something like

for i in a(b):print i

• If only a single value is yielded, print next(i()) will work too. Jun 23 '14 at 13:35
• Or just do print[*a(b)] Jun 5 '17 at 0:59

When using Python 3, for your final print statement, use exit to save one char (note: this prints to STDERR, so you might not be able to use this):

print('x')
exit('x')


exit even adds a trailing newline. There is one caveat, however: exit(some_integer) will not print.

• Does this print to STDOUT or STDERR? This sounds like it would be the latter, but in most challenges only the former is allowed. Apr 19 '15 at 4:24
• @Sp3000 I don't know... how can I tell? Apr 19 '15 at 5:18
• Seems to be stderr Apr 19 '15 at 5:32
• exit(some_integer) is valid because exit code is a default output form. Jun 23 '20 at 15:20

# Shorter isinstance

isinstance(x,C) # 15 bytes


there are several alternatives:

x.__class__==C  # 14 bytes
'a'in dir(x)    # 12 bytes, if the class has a distinguishing attribute 'a'
type(x)==C      # 10 bytes, doesn't work with old-style classes
'K'inx        # 8 bytes, only in python 2, if no other classes contain 'K'
# watch out for false positives from the hex address


Some of them may save extra bytes depending on the context, because you can eliminate a space before or after the expression.

Thanks Sp3000 for contributing a couple of tips.

## Avoid the repeat argument of itertools.product

As @T.Verron points out, in most cases (e.g. ranges and lists), you can instead do

product(*[x]*n)


However, even if you have a generator which you can only use once, like a Python 3 map, the repeat argument is still unnecessary. In such a case you can use itertools.tee:

product(x,repeat=n)
product(*tee(x,n))


For n = 2 you don't even need to include n, since 2 is the default argument to tee.

• product(*[L]*n) is even shorter. Oct 8 '15 at 11:59
• @T.Verron The initial use case I had in mind was something like a Python 3 map, for which that wouldn't work, but I'll add it as a note thanks :) Oct 8 '15 at 12:05
• Doesn't feersum have an open 500-point bounty for using itertools at all in a sufficiently old question? Oct 8 '15 at 13:17

## Optional empty sequence argument

Suppose we want to write a recursive function that prepends to a sequence (e.g. list, tuple) each time. For example, the Python 3 program

def f(n,k,L=[]):n and[f(n-1,k,[b]+L)for b in range(k)]or print(L)


works like itertools.product, taking n,k and printing all length n lists of numbers taken from range(k). (Example thanks to @xnor)

If we don't need L to be a list specifically, we can save on the optional empty list argument by making use of unpacking, like so:

def f(n,k,*T):n and[f(n-1,k,b,*T)for b in range(k)]or print(T)


where T is now a tuple instead. In the general case, this saves 3 bytes!

In Python 3.5+, this also works if we're appending to the end of a sequence, i.e. we can change f(n-1,k,L+[b]) to f(n-1,k,*T,b). The latter is a syntax error in earlier versions of Python though.

# Use slicing + assignment instead of mutator methods

l.insert(x,y) # before
l[x:x]=y,     # after

l.reverse()   # before
l[::-1]=l     # after

l.append(x)   # before
l[L:]=x,      # after (where L is any integer >= len(l))

l[:]=x        # set the contents of l to the contents of x


EDIT: thanks to @quintopia for pointing this out, these are statements, not expressions. The mutator methods are void functions, so they are expressions which evaluate to None. This means that things like [l.reverse() for x in L] and condition or l.reverse() are valid, whereas [l[::-1]=l for x in L] and condition or l[::-1]=l are not.

• Note that this cannot always be done. For instance, when using or or and as conditionals, assignment is not allowed, but append and the like are. Jan 13 '16 at 5:34
• l[:]=x is a bit unpythonic - same number of bytes, but I reckon l=x[:] is better practice. Also, [::-1] is listed as a tip here, L[:x]+=y, is better for the general case where x might be an expression (but same byte count if it's just x), and l+=x, is listed here for append. Feb 17 '16 at 7:10
• @Sp3000 l[:]=x and l=x[:] do different things. The former mutates the list itself, i.e. all references to that list, whereas the latter sets the variable l to a copy of x Feb 17 '16 at 7:47
• @Cyoce Oh, nevermind then - my eyes are going to have to get used to seeing that :P Feb 17 '16 at 8:01

## Use IDLE 3.3 to take multiline input

In IDLE versions 3.1 to 3.3, the command input() reads an entire multiline string like "line1\nline2", rather than a single line at a time as per the spec. This was fixed in version 3.4.

Calling input() only once is very convenient for golfing. Whether one can take advantage of this is debatable, but I think it is an acceptable interpreter- or environment-specific behavior.

• Wait... so how do you... sort of, enter the string if Enter adds a newline rather than EOF? Does CTRL+D work on Windows?
– cat
Mar 4 '16 at 3:00
• @tac I copy-paste it into IDLE.
– xnor
Mar 4 '16 at 3:30

## Easiest way to swap two values

>>> a=5
>>> b=4
>>> a,b=b,a
>>> a
4
>>> b
5


Access list, while building it inside comprehension

In python version 2.4 (and <2.3 with some tweaks) it is possible to access list, from list comprehension. Source #1, Source #2 (Safari, Python Cookbook, 2nd edition)

Python creates secret name _[1] for list, while it is created and store it in locals. Also names _[2], _[3]... are used for nested lists.

So to access list, you may use locals()['_[1]'].

In earlier versions this is not enough. You'll need to use locals()['_[1]'].__self__

I couldn't find evidence, that somethins like that is possible in versions >2.4

Don't think, that it might be usefull often, but who knows! At least it helps with building one-liners.

Example:

# Remove duplicates from a list:
>>> L = [1,2,2,3,3,3]
>>> [x for x in L if x not in locals()['_[1]']]
[1,2,3]

• This still exists in later Pythons. In Python 3, it's called '.0', and it's a generator. Aug 18 '17 at 6:42

To assign to a tuple, don't use parentheses. For example, a=1,2,3 assigns a to the tuple (1, 2, 3). b=7, assigns b to the tuple (7,). This works in both Python 2 and Python 3.

# Shorter way to copy/clone a list

(not deep clone. For deep clone see this answer)

a=x[:]
b=[*x]
c=x*1


Try it online!

# Slicing tricks for hard-wired lists of strings

Warning: Python is the language which worships readability above all else; so coding this way is a Mortal Sin.

This sort of thing comes up a lot; such as here where for a given digit in 0<=d<=9, we can get the 7-bit segment b value as a hex string from the list

b=['7e','30','6d','79','33','5b','5f','70','7f','7b'][d]


If the length of such a list is more than just a few elements, you're usually better off at least using split because you can replace a bunch of "','"s with a single character " " as delimiter. E.g.:

b='7e 30 6d 79 33 5b 5f 70 7f 7b'.split()[d]


This can be used for almost any list of strings (possibly at a small additional cost using a delimiter such as ",").

But if in addition, the strings we are selecting for all have the same length k (k==2 in our example), then with the magic of Python slicing, we can write the above as:

b='7e306d79335b5f707f7b'[2*d:][:2]


which saves a lot of bytes because we don't need character delimiters at all. But in that case, usually even shorter would be:

b='7367355777e0d93bf0fb'[d::10]


### Unpacking in Python3

If you only need the first few values in the array

>>> a, b, *c = [1, 2, 3, 4, 5]
>>> a
1
>>> b
2
>>> c
[3, 4, 5]


Same applies to when you need last few values

>>> *a, b, c = [1, 2, 3, 4, 5]
>>> a
[1, 2, 3]
>>> b
4
>>> c
5


Or even with the first few and last few

>>> a, *b, c = [1, 2, 3, 4, 5]
>>> a
1
>>> b
[2, 3, 4]
>>> c
5

• I was experimenting with this, and I found out you can also initialise an empty array if the number of values is one less than the number of variables, such as a,*b,c=1,2 or a,*b,c="ab"`
– Jo King
Oct 22 '18 at 11:25