Translate and use maketrans for closures in python

  • 2020-04-02 14:00:00
  • OfStack

Python's handling of strings is relatively efficient and has many methods. Two methods, maketrans and translate, have been used a lot. This paper summarizes the usage of these two methods.

Let's first review these two methods:

(1) s.slate (table, STR) removes the characters contained in STR from the string s, and replaces the remaining strings with the character mapping relationship in the table. Table can be understood as a conversion table, comparing 'a' - > 'A', 'b' - > 'B'.

Tabel = string.maketrans('s1', 's2') the length of s1 and s2 must be the same. Maketrans generates a conversion table. If there is s1 in s, replace it with s2.

A few examples:


import string
s = 'helloworld, 0001111'
table = string.maketrans('','')# No mapping, keep the original string 
s.translate(table) #hello world, 0001111
s.translate(table, 'hello000)'#world, 1111
table = string.maketrans('abcdefgh','ABCDEFGH')
s.translate(table)#HEllo,worlD,0001111
s.translate(table,'world')#HEllo,0001111

We can now wrap makerans,translate, into a factory function that returns the closure (print is the factory function) as follows:


import string
def translator(frm = '', to='', delete= '', keep = None):
  if len(to) == 1:
    to = to * len(frm)
  trans = string.maketrans(frm, to)
  if keep is not None:
    allchars = string.maketrans('','')
    delete = allchars.translate(allchars, keep.translate(allchars, delete))
    def translate(s):
      return s.translate(trans, delete)
    return translate

The function ends with a closure, which is a function that has access to a variable in another function's scope. A common way to create a closure is to create another function inside a function:


def make_adder(addend):
   def adder(augend): return augend + addend
   return adder

Executing p = make_addr(23) produces a closure of the inner function addr that internally references the name addend, which in turn binds to the value 23, and p(100) returns 123.

Now we've closed the possibilities behind a proposed interface.


>>>digits_only = translator(keep = string.digits)
>>>digits_only('Chris Perkins :224 -7992')
'2247992'

Removing elements belonging to a set of characters is also very simple:


>>>no_digits = translator(delete = string.digits)
>>>no_digits('Chris Perkins:224-7992')
'Chris Perkings : - '

Can also be replaced:


>>>digits_to_hash = translator(from = string.digits, to = '#')
>>>digits_to_hash('Chris Perkins :224-7992')
'Chris Perkins: ###-####'

When delete and keep overlap, the delete parameter takes precedence


>>>trans = translator(delete = 'abcd', kepp ='cdef')
>>>trans('abcdefg')
'ef'

In fact, we can add some exceptions in more detail to handle the situation of delete and keep.

I hope this article has helped you with your Python programming.


Related articles: