title: latin-1 to ascii
body: <p>I have a unicode string with accented latin chars e.g.</p>
  
  <pre><code>n=unicode('Wikipédia, le projet d’encyclopédie','utf-8')
  </code></pre>
  
  <p>I want to convert it to plain ascii i.e. 'Wikipedia, le projet dencyclopedie', so all acute/accent,cedilla etc should get removed</p>
  
  <p>What is the fastest way to do that, as it needed to be done for matching a long autocomplete dropdown list</p>
  
  <p><strong>Conclusion:</strong>
  As one my criteria is speed, Lennart's 'register your own error handler for unicode encoding/decoding' gives best result (see Alex's answer), speed difference increases further  as more and more chars are latin.</p>
  
  <p>Here is the translation table I am using, also modified error handler as it need to take care of whole range of un-encoded char from error.start to error.end</p>
  
  <pre><code># -*- coding: utf-8 -*-
  import codecs
  
  """
  This is more of visual translation also avoiding multiple char translation
  e.g. £ may be written as {pound}
  """
  latin_dict = {
  u"¡": u"!", u"¢": u"c", u"£": u"L", u"¤": u"o", u"¥": u"Y",
  u"¦": u"|", u"§": u"S", u"¨": u"`", u"©": u"c", u"ª": u"a",
  u"«": u"&lt;&lt;", u"¬": u"-", u"­": u"-", u"®": u"R", u"¯": u"-",
  u"°": u"o", u"±": u"+-", u"²": u"2", u"³": u"3", u"´": u"'",
  u"µ": u"u", u"¶": u"P", u"·": u".", u"¸": u",", u"¹": u"1",
  u"º": u"o", u"»": u"&gt;&gt;", u"¼": u"1/4", u"½": u"1/2", u"¾": u"3/4",
  u"¿": u"?", u"À": u"A", u"Á": u"A", u"Â": u"A", u"Ã": u"A",
  u"Ä": u"A", u"Å": u"A", u"Æ": u"Ae", u"Ç": u"C", u"È": u"E",
  u"É": u"E", u"Ê": u"E", u"Ë": u"E", u"Ì": u"I", u"Í": u"I",
  u"Î": u"I", u"Ï": u"I", u"Ð": u"D", u"Ñ": u"N", u"Ò": u"O",
  u"Ó": u"O", u"Ô": u"O", u"Õ": u"O", u"Ö": u"O", u"×": u"*",
  u"Ø": u"O", u"Ù": u"U", u"Ú": u"U", u"Û": u"U", u"Ü": u"U",
  u"Ý": u"Y", u"Þ": u"p", u"ß": u"b", u"à": u"a", u"á": u"a",
  u"â": u"a", u"ã": u"a", u"ä": u"a", u"å": u"a", u"æ": u"ae",
  u"ç": u"c", u"è": u"e", u"é": u"e", u"ê": u"e", u"ë": u"e",
  u"ì": u"i", u"í": u"i", u"î": u"i", u"ï": u"i", u"ð": u"d",
  u"ñ": u"n", u"ò": u"o", u"ó": u"o", u"ô": u"o", u"õ": u"o",
  u"ö": u"o", u"÷": u"/", u"ø": u"o", u"ù": u"u", u"ú": u"u",
  u"û": u"u", u"ü": u"u", u"ý": u"y", u"þ": u"p", u"ÿ": u"y", 
  u"’":u"'"}
  
  def latin2ascii(error):
      """
      error is  protion of text from start to end, we just convert first
      hence return error.start+1 instead of error.end
      """
      return latin_dict[error.object[error.start]], error.start+1
  
  codecs.register_error('latin2ascii', latin2ascii)
  
  if __name__ == "__main__":
      x = u"¼ éíñ§ÐÌëÑ » ¼ ö ® © ’"
      print x
      print x.encode('ascii', 'latin2ascii')
  </code></pre>
  
  <p><strong>Why I return <code>error.start + 1</code>:</strong></p>
  
  <p>error object returned can be multiple characters, and we convert only first of these e.g. if I add <code>print error.start, error.end</code> to error handler output is</p>
  
  <pre><code>¼ éíñ§ÐÌëÑ » ¼ ö ® © ’
  0 1
  2 10
  3 10
  4 10
  5 10
  6 10
  7 10
  8 10
  9 10
  11 12
  13 14
  15 16
  17 18
  19 20
  21 22
  1/4 einSDIeN &gt;&gt; 1/4 o R c '
  </code></pre>
  
  <p>so in second line we get chars from 2-10 but we convert only 2nd hence return 3 as continue point, if we return error.end output is</p>
  
  <pre><code>¼ éíñ§ÐÌëÑ » ¼ ö ® © ’
  0 1
  2 10
  11 12
  13 14
  15 16
  17 18
  19 20
  21 22
  1/4 e &gt;&gt; 1/4 o R c '
  </code></pre>
  
  <p>As we can see 2-10 portion has been replaced by a single char. off-course it would be faster to just encode whole range in one go and return error.end, but for demonstration purpose I have kept it simple.</p>
  
  <p>see <a href="http://docs.python.org/library/codecs.html#codecs.register_error" rel="noreferrer">http://docs.python.org/library/codecs.html#codecs.register_error</a> for more details</p>