从列Numb中获取Excel样式的列名

2024-05-16 22:23:17 发布

您现在位置:Python中文网/ 问答频道 /正文

这是在提供行和列ID时提供列名的代码,但是当我提供类似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值,并期望相同的字母值。)


Tags: and代码dividmodcolumncolcz
3条回答

有几个索引问题:

因此,要解决问题,您需要使所有索引匹配:

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

编辑:我觉得我必须承认,正如其他一些从未给我留下评论的人所指出的,我的回答的前一个版本(您接受了)有一个错误,使它无法正确处理大于702(对应于Excel列'ZZ')的列号。所以,为了正确起见,下面的代码已经修复了这个问题,它现在包含了一个循环,就像许多其他答案一样。

很可能您从未使用过列号足够大的前一个版本来遇到此问题。例如,MS specs for the current version of Excel说它支持多达16384列的工作表(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'

我喜欢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

相关问题 更多 >