Python Code Golfing Tips

Various Python code golfing tips. Intended to be a continuation of Mark Byers’ original Python code golfing tips.

Glossary

Conventions

Contributors

Doing nothing

1B: Absolutely optimal.

0

Reading from stdin

Read all input, possibly multiple lines

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

Read all lines in a list

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

Iterate over all lines

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:[...]

Read one line without trailing newline

13B: Trivial.

A=raw_input()

Read one integer

9B: Trivial.

A=input()

Read a fixed number of lines without trailing newline

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)

Read one line with columns separated by whitespace

21B: Trivial. Returns a list.

A=raw_input().split()

Read one line with integers separated by whitespace

30B: Trivial. Returns a list.

A=map(int,raw_input().split())

Read one line with columns separated by comma

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

Writing to stdout

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

Common values

A set with characters 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`)

Conversion

Convert a list of characters to a string

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]

Convert a list of ASCII character codes to a string

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

Convert a number to a string

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`

List operations and loops

Create a list with given number of elements

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)

Loop for given number of iterations

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

Append one element to the end of a list

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,

Arithmetic/numeric operations

Increment/decrement by one

2B: Trivial.

A-1
A+1

2B: Preferred when the binary operator causes parentheses. Uses a two’s complement identity.

~-A
-~A

Is this number a prime?

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

Logical operations

And operator

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

If-then-else

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]

0 if zero, 1 otherwise

3B: Trivial.

0!=A

1 if zero, 0 otherwise

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

Other guidelines

Optimal indentation

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.

Removing redundant whitespace

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

TODO


ikiwiki를 씁니다.
마지막 수정