6
votes

I need convert numeric strings to superscript, is there a better (built-in) way of doing it?

def to_sup(s):
    sups={u'1': u'\xb9', 
          u'0': u'\u2070',
          u'3': u'\xb3', 
          u'2': u'\xb2',
          u'5': u'\u2075',
          u'4': u'\u2074',
          u'7': u'\u2077',
          u'6': u'\u2076',
          u'9': u'\u2079',
          u'8': u'\u2078'}
    if s.isdigit():
        return ''.join([sups[i] for i in s])
print to_sup('0123')

Output:

⁰¹²³
1
Completely off-topic: I would not use Unicode directly for such formatting details, and rather emit some intermediate markup code that could be typeset properly by some external engine, which in turn can choose to use OpenType style features (superscript? numerator? oldstyle or lining?) depending on the details of the use case. - Kerrek SB
@KerrekSB, using OpenType "sups" feature requires advanced rendering software and requires OpenType information in the font being used, and when it works, it ends up with using the same glyphs as with the Unicode superscript characters. It is possible though that some font has superscript glyphs defined only as OpenType variants of normal digits. - Jukka K. Korpela

1 Answers

9
votes

Your way is slightly incorrect. Better would be:

def to_sup(s):
    sups = {u'0': u'\u2070',
            u'1': u'\xb9',
            u'2': u'\xb2',
            u'3': u'\xb3',
            u'4': u'\u2074',
            u'5': u'\u2075',
            u'6': u'\u2076',
            u'7': u'\u2077',
            u'8': u'\u2078',
            u'9': u'\u2079'}

    return ''.join(sups.get(char, char) for char in s)  # lose the list comprehension

s.isdigit() will only check the first letter, which probably doesn't make sense.

If for some reason you want a one-liner:

u''.join(dict(zip(u"0123456789", u"⁰¹²³⁴⁵⁶⁷⁸⁹")).get(c, c) for c in s)