Convert an excel or spreadsheet column letter to its number in Pythonic fashion Convert an excel or spreadsheet column letter to its number in Pythonic fashion python python

Convert an excel or spreadsheet column letter to its number in Pythonic fashion


There is a way to make it more pythonic (works with three or more letters and uses less magic numbers):

def col2num(col):    num = 0    for c in col:        if c in string.ascii_letters:            num = num * 26 + (ord(c.upper()) - ord('A')) + 1    return num

And as a one-liner using reduce (does not check input and is less readable so I don't recommend it):

col2num = lambda col: reduce(lambda x, y: x*26 + y, [ord(c.upper()) - ord('A') + 1 for c in col])


One-liners tested in Python 2.7.1 and 3.5.2

excel_col_num = lambda a: 0 if a == '' else 1 + ord(a[-1]) - ord('A') + 26 * excel_col_num(a[:-1])excel_col_name = lambda n: '' if n <= 0 else excel_col_name((n - 1) // 26) + chr((n - 1) % 26 + ord('A'))

Multi-liners likewise

def excel_column_name(n):    """Number to Excel-style column name, e.g., 1 = A, 26 = Z, 27 = AA, 703 = AAA."""    name = ''    while n > 0:        n, r = divmod (n - 1, 26)        name = chr(r + ord('A')) + name    return namedef excel_column_number(name):    """Excel-style column name to number, e.g., A = 1, Z = 26, AA = 27, AAA = 703."""    n = 0    for c in name:        n = n * 26 + 1 + ord(c) - ord('A')    return ndef test (name, number):    for n in [0, 1, 2, 3, 24, 25, 26, 27, 702, 703, 704, 2708874, 1110829947]:        a = name(n)        n2 = number(a)        a2 = name(n2)        print ("%10d  %-9s  %s" % (n, a, "ok" if a == a2 and n == n2 else "error %d %s" % (n2, a2)))test (excel_column_name, excel_column_number)test (excel_col_name, excel_col_num)

All tests print

         0             ok         1  A          ok         2  B          ok         3  C          ok        24  X          ok        25  Y          ok        26  Z          ok        27  AA         ok       702  ZZ         ok       703  AAA        ok       704  AAB        ok   2708874  EXCEL      ok1110829947  COLUMNS    ok


Here is one way to do it. It is a variation on code in the XlsxWriter module:

def col_to_num(col_str):    """ Convert base26 column string to number. """    expn = 0    col_num = 0    for char in reversed(col_str):        col_num += (ord(char) - ord('A') + 1) * (26 ** expn)        expn += 1    return col_num>>> col_to_num('A')1>>> col_to_num('AB')28>>> col_to_num('ABA')729>>> col_to_num('AAB')704