Thursday, December 4, 2014

better translate()

translate is a simple, efficient function for doing fast byte-by-byte replacement on a string in Python.

However, Python Does What is always on the lookout for dangerous alternatives to simple things.  Instead of a function call, isn't it better to mutate global interpreter state so that the same result is achieved as a side-effect of a completely different operation?  (The answer is yes.)

>>> import ctypes
>>> def maketrans(inp, outp):
...    inp = list(inp)
...    outp = list(outp)
...    for aa, bb in zip(inp, outp):  # there's a fun reason single letter variable names are a bad idea here
...       ctypes.memset(ctypes.pythonapi.PyString_AsString(id(aa)), ord(bb), 1)
>>> maketrans("jkl", "xyz")
>>> "".join("jkl")

This method also has application to single character variable names that bears further exploration.

yade (yet another dict extension)

>>> from collections import defaultdict
>>> class TypeDict(dict):
...    def __missing__(self, key):
...       self[key] = defaultdict(key)
...       return self[key]
>>> td = TypeDict()
>>> td[float]['test']