Store lookup tables as magic numbers
Say you want to hardcode a Boolean lookup table, like which of the first twelve English numbers contain an n.
Then, you can implement this lookup table concisely as:
with the resulting 0 ...
Collapse two numerical loops into one
Say you're iterating over the cells of an m*n grid. Instead of two nested for loops, one for the row and one of the columns, it's usually shorter to use a single loop to iterate over the m*n cells of the grid. You can extract the row and column of the cell inside the loop.
for i in range(m):
for j in ...
For integer n, you can write
n+1 as -~n
n-1 as ~-n
because the bit flip ~x equals -1-x. This uses the same number of characters, but can indirectly cut spaces or parens for operator precedence.
while n-1: #Same as while n!=1
The operators ~ and unary - are ...
A nice way to convert an iterable to list on Python 3:
imagine you have some iterable, like
i = (1,2,3,4)
i = range(4)
i = (x**2 for x in range(5))
But you need a list:
x=list(i) #the default way
*x,=i #using starred assignment -> 4 char fewer
It's very useful to make a list of chars out of a string
This isn't the same solution as llhuii's, but it's also 42 bytes long.
Try it online!
Thanks to @JonathanFrech, we're now at 40 bytes.
Try it online!
There's another byte to be saved, for a total of 39.
Try it online!
Instead of range(x), you can use the * operator on a list of anything, if you don't actually need to use the value of i:
for i in*8:pass
as opposed to
for i in range(8):pass
If you need to do this more than twice, you could assign any iterable to a variable, and multiply that variable by the range you want:
for i in r*8:pass
for i in r*1000:pass
Extended iterable unpacking ("Starred assignment", Python 3 only)
The best way to explain this is via an example:
[1, 2, 3]
We've already seen a use for this — turning an iterable into a list in Python 3:
Here are a few more uses.
Getting the ...
For ages it bothered me that I couldn't think of a short way to get the entire alphabet. If you use range enough that R=range is worth having in your program, then
[chr(i+97)for i in R(26)]
is shorter than the naive
, but otherwise it's longer by a single character. It haunted me that the clever one that required some ...
Try it online!
The method is similar to Dennis' second (deleted) answer, but this answer is easier to be proved correct.
The most significant digit of (4**n+1)**n%4**n**2 in base \$2^n\$ that is not divisible by \$n\$ will make the next (less significant) digit in (4**n+1)**n%...
Python 3 does not have cmp. For golfing, you can do
which loses 3 chars over cmp(a,b).
Amusingly, this is also an "official" workaround. The What's New in Python 3 page says "(If you really need the cmp() functionality, you could use the expression (a > b) - (a < b) as the equivalent for cmp(a, b).)"
Although python doesn't have switch statements, you can emulate them with dictionaries. For example, if you wanted a switch like this:
You could use if statements, or you could use this:
When you have two boolean values, a and b, if you want to find out if both a and b are true, use * instead of and:
if a and b: #7 chars
if a*b: #3 chars
if either value is false, it will evaluate as 0 in that statement, and an integer value is only true if it is nonzero.
Python 3, 22 (Possibly not allowed)
If the challenge is "to create a python script which prints the even numbers from 0 to 100" and not "to create a python script which prints the even numbers from 0 to 100, newline separated", then the shortest solution is:
Remember, it's very important in code golf not to put any limitations on ...
No problemo! You can alias a method, but you have to know how to use it:
The key is that you have to pass self explicitly, because the alias is a kind of function that takes an extra argument that takes self:
Getting 39 bytes
This is an explanation of how I got a 39-byte solution, which Dennis and JonathanFrech found separately as well. Or, rather, it explains how one could arrive at the answer in hindsight, in a way that's much nicer than my actual path to it, which was full of muddy reasoning and dead ends.
Exploit Python 2 string representations
Python 2 lets you convert an object x to its string representation `x` at a cost of only 2 chars. Use this for tasks that are easier done on the object's string than the object itself.
Given a list of characters l=['a','b','c'], one can produce ''.join(l) as `l`[2::5], which saves a byte.
Use ~ to index from the back of a list
If L is a list, use L[~i] to get the i'th element from the back.
This is the i'th element of the reverse of L. The bit complement ~i equals -i-1, and so fixes the off-by-one error from L[-i].
Ceil and Floor
If you ever want to get the rounded-up result for a division, much like you'd do with // for floor, you could use math.ceil(3/2) for 15 or the much shorter -(-3//2) for 8 bytes.
math.floor(n) : 13 bytes+12 for import
n//1 : 4 bytes
math.ceil(n) : 12 bytes+12 for import
-(-n//1) : 8 bytes
Choosing one of two numbers based on a condition
You already know to use the list selection [x,y][b] with a Boolean b for the ternary expression y if b else x. The variables x, y, and b can also be expressions, though note that both x and y are evaluated even when not selected.
Here's some potential optimizations when x and y are numbers.
[0,y][b] -> y*...
Change import * to import*
If you haven't heard, import* saves chars!
from math import*
is only 1 character longer than import math as m and you get to remove all instances of m.
Even one time use is a saver!
Use += instead of append and extend
can be shortened to:
B, here creates a one-element tuple which can be used to extend A just like [B] in A+=[B].
can be shortened to:
PEP448 – Additional Unpacking Generalizations
With the release of Python 3.5, manipulation of lists, tuples, sets and dicts just got golfier.
Turning an iterable into a set/list
Compare the pairs:
Much shorter! Note, however, that if you just want to convert something to a list and assign it to a variable, ...
Length tradeoff reference
I've think it would be useful to have a reference for the character count differences for some common alternative ways of doing things, so that I can know when to use which. I'll use _ to indicate an expression or piece of code.
Assign to a variable: +4
So, this breaks even if you
Use _ a second time: _ has length 5
Here's a whole bunch of micro-optimisations you can do:
Use .split() to create a long list (-17 bytes):
c=['yellow','blue','white','green','Black', 'purple', 'silver', 'cyan', 'magenta', 'red']
c='yellow blue white green Black purple silver cyan magenta red'.split()
Remove extraneous brackets (-2 bytes):