从列号中获取Excel样式的列名称

这是在提供行和列ID时提供COLUMN名称的代码,但是当我给出像row = 1 and col = 104这样的值时,它应该返回CZ ,但是它返回D@

 row = 1 col = 104 div = col column_label = str() while div: (div, mod) = divmod(div, 26) column_label = chr(mod + 64) + column_label print column_label 

我在做什么错?

(这个代码是EXCEL列的参考,其中我提供行,列ID值,并期望ALPHABETIC值相同。)

编辑:我觉得我必须承认,正如其他一些人一样 – 他们从来没有留给我评论 – 我的答案的前一个版本(您接受)有一个错误,使得它无法正确处理大于702列数(对应的到Excel专栏'ZZ' )。 所以,为了正确性,已经在下面的代码中修复了,正如其他许多答案一样,它现在包含一个循环。

很有可能你从来没有使用以前的版本足够大的列号来遇到问题。 FWIW, 当前版本的Excel的MS规格说,它支持多达16,384列(Excel列'XFD' )的工作表。

 LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' def excel_style(row, col): """ Convert given row and column number to an Excel-style cell name. """ result = [] while col: col, rem = divmod(col-1, 26) result[:0] = LETTERS[rem] return ''.join(result) + str(row) if __name__ == '__main__': addresses = [(1, 1), (1, 26), (1, 27), (1, 52), (1, 53), (1, 78), (1, 79), (1, 104), (1, 18253), (1, 18278), (1, 702), # -> 'ZZ1' (1, 703), # -> 'AAA1' (1, 16384), # -> 'XFD1' (1, 35277039)] print('({:3}, {:>10}) --> {}'.format('row', 'col', 'Excel')) print('==========================') for row, col in addresses: print('({:3}, {:10,}) --> {!r}'.format(row, col, excel_style(row, col))) 

输出:

 (row, col) --> Excel ======================== ( 1, 1) --> 'A1' ( 1, 26) --> 'Z1' ( 1, 27) --> 'AA1' ( 1, 52) --> 'AZ1' ( 1, 53) --> 'BA1' ( 1, 78) --> 'BZ1' ( 1, 79) --> 'CA1' ( 1, 104) --> 'CZ1' ( 1, 18253) --> 'ZZA1' ( 1, 18278) --> 'ZZZ1' ( 1, 702) --> 'ZZ1' ( 1, 703) --> 'AAA1' ( 1, 16384) --> 'XFD1' ( 1, 35277039) --> 'BYEBYE1' 

你有几个索引问题:

所以要解决你的问题,你需要使所有的索引匹配:

 def colToExcel(col): # col is 1 based excelCol = str() div = col while div: (div, mod) = divmod(div-1, 26) # will return (x, 0 .. 25) excelCol = chr(mod + 65) + excelCol return excelCol print colToExcel(1) # => A print colToExcel(26) # => Z print colToExcel(27) # => AA print colToExcel(104) # => CZ print colToExcel(26**3+26**2+26) # => ZZZ 

我喜欢maritineau的答案,因为它的代码看起来简单易懂。 但它不能处理大于26 ** 2 + 26的列号。所以我修改了一部分。

 def excel_col(col): """Covert 1-relative column number to excel-style column label.""" quot, rem = divmod(col-1,26) return excel_col(quot) + chr(rem+ord('A')) if col!=0 else '' if __name__=='__main__': for i in [1, 26, 27, 26**3+26**2+26]: print 'excel_col({0}) -> {1}'.format(i, excel_col(i)) 

结果

 excel_col(1) -> A excel_col(26) -> Z excel_col(27) -> AA excel_col(18278) -> ZZZ 

我认为这是这样的:

 def get_col(col): """Get excel-style column names""" (div, mod) = divmod(col, 26) if div == 0: return str(unichr(mod+64)) elif mod == 0: return str(unichr(div+64-1)+'Z') else: return str(unichr(div+64)+unichr(mod+64)) 

一些testing:

 >>> def get_col(col): ... (div, mod) = divmod(col, 26) ... if div == 0: ... return str(unichr(mod+64)) ... elif mod == 0: ... return str(unichr(div+64-1)+'Z') ... else: ... return str(unichr(div+64)+unichr(mod+64)) ... >>> get_col(105) 'DA' >>> get_col(104) 'CZ' >>> get_col(1) 'A' >>> get_col(55) 'BC' 

我想我明白了。 divmod(104,26)给出mod = 0,这使得chr(0 + 64)= 64即'@'。

如果我添加此行之前column_label "mod=26 if mod==0 else mod"我认为它应该工作正常

 column_label='' div=104 while div: (div, mod) = divmod(div, 26) mod=26 if mod==0 else mod column_label = chr(mod + 64) + column_label print column_label 

使用这个代码:

 def xlscol(colnum): a = [] while colnum: colnum, remainder = divmod(colnum - 1, 26) a.append(remainder) a.reverse() return ''.join([chr(n + ord('A')) for n in a]) 
 def ColNum2ColName(n): convertString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" base = 26 i = n - 1 if i < base: return convertString[i] else: return ColNum2ColName(i//base) + convertString[i%base] 

编辑:对,正确的zondo。

我刚刚走近A, B, .. AA, AB, ...作为数字AZ的数字基地。

 A = 1 B = 2 . . X = 24 Y = 25 Z = 26 . . . 

这是一个简单的方法,没有任何while循环等,并适用于任何数量> 0