Various Python code golfing tips. Intended to be a continuation of Mark Byers’ original Python code golfing tips.
os.read
etc.). Many solutions do work for any platforms however.import
or short reference to longer function names, then both the byte count including such import
s and assignments and the byte count without them is shown.A*2+1
counts as 4B.[...]
can be replaced with one or more statements that don’t count towards to the byte count but nevertheless required. You need to use one more byte if you want to do nothing.[;...]
can be replaced with zero or more statements (with a preceding semicolon as required) that don’t count towards to the byte count. You can omit it entirely in order to do nothing.^
below.1B: Absolutely optimal.
0
27B/17B: Optimal in most cases.
import os;A=os.read(0,9**9)
26B/16B: Was optimal in most cases, but doesn’t work in the recent version of Python.
import os;A=os.read(0,9e9)
25B/15B: Works only when your input is always less than 100 bytes.
import os;A=os.read(0,99)
29B/18B: Useful only when you already require sys
for some other reason.
import sys;A=sys.stdin.read()
25B: Leaves a trailing newline in each line. Works only when the system supports /dev/fd
. If the system puts a Python file to a directory directly in the root directory (e.g. /root
) then '/dev/fd/0'
can be replaced by '../fd/0'
(23B).
A=list(open('/dev/fd/0'))
28B/17B: Leaves a trailing newline in each line.
import sys;A=list(sys.stdin)
39B/29B: Leaves no trailing newline in each line.
import os;A=os.read(0,9**9).split('\n')
35B/25B: Leaves no trailing newline in each line. Works only when preceding and trailing whitespace in each line is insignificant.
import os;A=os.read(0,9**9).split()
30B: Leaves a trailing newline in each line.
import sys
for L in sys.stdin:[...]
21B: Leaves no trailing newline in each line, but causes an exception at the end. Useful only when the system is exception tolerant and you don’t have a code after the loop.
while 1:L=raw_input()[;...]
35B: Leaves no trailing newline in each line and allows for arbitrary code after the loop.
try:
while 1:L=raw_input()[;...]
except:[...]
13B: Trivial.
A=raw_input()
9B: Trivial.
A=input()
Replace raw_input
with input
for reading a fixed number of integers or any valid Python expression.
13B: Optimal for one line.
A=raw_input()
21B: Optimal for two lines. Returns a tuple.
R=raw_input;A=R(),R()
23B+: Optimal for three lines (and more). Returns a list.
A=map(raw_input,['']*3)
21B: Trivial. Returns a list.
A=raw_input().split()
30B: Trivial. Returns a list.
A=map(int,raw_input().split())
24B: Trivial. Returns a list.
A=raw_input().split(',')
9B: Works only when each column is also a valid Python expression (e.g. number) and there are always two or more columns. Returns a tuple.
A=input()
5B: Trivial.
print
4B: Useful only when you have to call input
or raw_input
right after printing.
input('\n')
^^^^
7B: Trivial.
print V
6B: Useful only when you have to call input
or raw_input
right after printing and S
is a string.
input(V+'\n')
^^^^^^
8B: Leaves a trailing whitespace unless the next print
has no arguments.
print S,
23B/13B: Leaves no trailing whitespace. In general you should avoid this; join all outputs and print them at once instead.
import os;os.write(1,S)
1B: Useful only when you have to call input
or raw_input
right after printing.
input(S)
^
4B: Useful only when you have a short reference to input
or raw_input
and you don’t have any more code after printing.
I=input;I(S)
^^^^
If the solution involves a call to str
and your integer is a short integer (int
), then you can save further 3 bytes by replacing str(N)
with `N`
. See Convert a number to a string for further optimizations.
8B: Leaves a trailing whitespace unless the next print
has no arguments.
print N,
35B/24B: Leaves no trailing whitespace. In general you should avoid using this; join all outputs and print them at once instead.
import sys;sys.stdout.write(str(N))
6B: Useful only when you have to call input
or raw_input
right after printing.
input(str(N))
^^^^^^
1
to 9
This can also be used in the loop if you don’t mind the order. Remove a surrounding set(...)
(5B in total) in that case.
15B: Optimal in most cases. This exploits the fact that 5**18 == 25**9 == 3814697265625
, which includes every digit from 1 to 9. There are other values that work (for example, 52**8 == 53459728531456
) but this results in the minimal value. Courtesy of Scott Kirkwood.
set('%d'%5**18)
set('%d'%25**9)
12B: Works only when your Python is a 64-bit build. Otherwise it would include a stray L
.
set(`5**18`)
set(`25**9`)
9B: Trivial.
''.join(L)
8B: Useful only when the characters are limited to printable ASCII characters sans \
. In brief, `L`
will return something like ['A', 'b', '"', "'", ' ']
in which letters can be readily extracted with a slice.
`L`[2::5]
16B: Optimal in general. Requires Python 2.6. If you don’t need a full compatibility with str
(main differences include a mutability, a subscription yielding an integer and a repr
output) then you can remove a call to str
(11B).
str(bytearray(L))
18B: Optimal for Python 2.5 or earlier. See also Convert a list of characters to a string.
''.join(map(chr,L))
5B: Optimal when a number can be a long integer.
str(N)
5B: Useful only when N
is a simple expression (no infix operator). Preferred if you need to concatenate a fixed string after the conversion.
'%d'%N
2B: Useful only when the number is always a short integer.
`N`
17B: Works for any A
. Also see Loop for given number of iterations for further optimizations.
[A for X in'X'*N]
11B: Useful only when you may use a tuple instead of a list and the code fits in a string.
eval('A,'*N)
3B: Useful only when A
is immutable.
[A]*N
16B: Useful only when A
is []
. Saves one more byte.
map(list,[()]*N)
Every solution also applies to the list comprehension, which requires two or three more bytes for brackets and possible whitespace before for
.
18B: Trivial.
for I in range(N):[...]
12B/13B/15B/17B: Works only when N
is at most 4. Useful only when you want I
to be a proper induction variable.
for I in 0,:[...]
for I in 0,1:[...]
for I in 0,1,2:[...]
for I in 0,1,2,3:[...]
14B: Useful only when you have a short reference to range
or xrange
.
R=range
for I in R(N):[...]
^^^^^^^^^^^^^^
14B: Useful only when you don’t need an iteration variable and the loop body won’t fit in one line.
for I in'X'*N:[...]
9B: Useful only when you don’t need an iteration variable, the loop body does not contain both kinds of quotes (so that the code neatly fits in the string) and the loop body fits in one line. Not applicable to the list comprehension.
exec'[...];'*N
3B: Optimal in most cases. This is because +=
operator is equivalent to extend
method in the list and it accepts any iterator including a tuple.
L+=A,
2B: Trivial.
A-1
A+1
2B: Preferred when the binary operator causes parentheses. Uses a two’s complement identity.
~-A
-~A
14B: Works only when 0 < A < 561
. (Other counterexamples include 645 and 946.) This little code performs the Fermat primality test for a fixed base (here 10103) that covers a large number of small integers. Example.
10103**~-A%A<2
5B: Trivial. Short-circuiting behavior.
A and B
A and B and C
A and B and C and D
1B: Useful only when both A
and B
will be one of 0/False
or 1/True
and you don’t need a short-circuiting behavior. Requires parentheses around A
and B
if they contain comparisons.
A&B
A&B&C
A&B&C&D
3B: Useful only when both A
and B
will be non-negative or boolean and you don’t need a short-circuiting behavior.
A>0<B
A>0<B>0<C
A>0<B>0<C>0<D
13B: Trivial. Requires Python 2.5. Short-circuiting behavior.
A if C else B
12B: Pre-2.5 conditional expression. Short-circuiting behavior. Useful only when A
is always non-zero. Can be contracted to C and A
(7B) or C or B
(6B) if you need only one part of the conditional.
C and A or B
8B: Useful only when you don’t need short-circuiting behavior and C
is one of -1, 0 or 1. You may need to convert C
according to 0 if zero, 1 otherwise.
(B,A)[C]
8B: Short-circuiting behavior. Useful only when C
is either 0 or 1, A
is either a sequence or a number. If B
is 0 or False
then it can trivially reduced to C*A
(3B). You can remove redundant whitespace by swapping A
and C
.
C*A or B
A*C or B
6B (sorta): Useful only when you don’t need short-circuiting behavior, C
is either 0 or 1, A
and B
is both a string and len(B) - len(A)
is either 0 or 1. You may need to convert C
according to 0 if zero, 1 otherwise. The idea is that we can interleave a string to have A
in odd indices and B
in even indices. When we collect only odd indices (that is, [1::2]
) we get A
, and when we collect only even indices (that is, [0::2]
or [::2]
) we get B
. The length constraint is severe but it is still often useful.
'BABABABAB'[C::2]
3B: Trivial.
0!=A
3B: Trivial.
0==A
3B: Useful only when A
is a non-negative integer and you need higher precedence than ==
. Exploits the fact that 0**0
always evaluates to 1 in Python.
0**A
2B: Useful only when A
is non-negative/non-positive and don’t need parentheses.
0<A
0>A
If you need to indent more than two levels (which is not desirable for code golfing, but may be required sometimes), you can organize the indentation as follows:
if 1:
␣if 2:
→if 3:
→␣if 4:
→→if 5:
→→␣[...]
Here ␣
stands for a space character and →
stands for a tab character. This strangeness comes from how Python treats a tab character in the code: it inserts one to eight spaces up to the next eighth column. So in the example code the fourth line (one tab, one space) is thought to have 9 spaces before the code, and the fifth line (two tabs) is thought to have 16 spaces.
Python, besides from its significant indentation, allows the code to omit most whitespace between two lexical tokens. The rule of thumb is:
You can omit every whitespace unless it is preceded by an identifier letter and followed by an identifier letter or decimal digit. An identifier letter corresponds to an uppercase letter, lowercase letter or underscore(
_
) in Python 2.
This is a simplification of the actual parsing rule. Note that both rules allow for a code like 3if x else 4
, since 3i
and 3if
can’t be a valid token. (In fact, for example, 3lambda
does parses as 3l
and ambda
because 3l
is a valid token for long integers. But the current Python syntax doesn’t allow such cases.)
id('') % 5
)exec
for nested loops (exec'for x in ...:...\n'*k
)