获取 Excel 列标签(A、B、...、Z、AA、...、AZ、BA、...、ZZ、AAA、AAB、...)

Get the Excel column label (A, B, ..., Z, AA, ..., AZ, BA, ..., ZZ, AAA, AAB, ...)

给定 Excel 列的字母 header 我需要输出列号。

它是 A-Z,然后是 AA-AZ 然后是 BA-BZ 等等。

我想像以 26 为底数一样通过它,我只是不知道如何实现它。

它适用于像 AA 这样的简单的,因为 26^0 = 1 + 26^1 = 26 = 27.

但是对于 ZA 这样的东西,如果我这样做 26 ^ 26(z 是第 26 个字母),输出显然太大了。我错过了什么?

如果我们将“A”解码为 0,“B”解码为 1,...那么“Z”为 25,“AA”为 26。

所以它不是纯 26 基编码,因为前缀“A”对值没有影响,“AAAB”必须与“B”相同,就像在十进制0001等于1。但是这里不是这样。

“AA”的值为1*261 + 0,“ZA”的值为26*261 + 0 .

我们可以概括地说,“A”的值应为 1,“B”的值应为 2,...等(单个字母编码除外)。所以在“AAA”中,最右边的“A”代表系数为0,而其他的“A”代表系数:1*262 + 1*261 + 0

这导致以下代码:

def decode(code):
    val = 0
    for ch in code: # base-26 decoding "plus 1"
        val = val * 26 + ord(ch) - ord("A") + 1 
    return val - 1

当然,如果我们希望列号以 1 而不是 0 开头,那么只需将最后的语句替换为:

return val

幂和

你可以求出 26 的幂的倍数:

def xl2int(s):
    s = s.strip().upper()
    return sum((ord(c)-ord('A')+1)*26**i
               for i,c in enumerate(reversed(s)))

xl2int('A')
# 1

xl2int('Z')
# 26

xl2int('AA')
# 27

xl2int('ZZ')
# 702

xl2int('AAA')
# 703

int 内置

您可以使用带有 base 参数的字符串翻译 table 和 int 内置函数。

因为你有一个破损的基础,你需要为长度为 n 的输入添加 26**n+26**(n-1)+...+26**0,你可以用 int('11...1', base=26) 其中 1 的个数与输入字符串的长度一样多。

from string import ascii_uppercase, digits
t = str.maketrans(dict(zip(ascii_uppercase, digits+ascii_uppercase)))

def xl2int(s):
    s = s.strip().upper().translate(t)
    return int(s, base=26)+int('1'*len(s), base=26)

xl2int('A')
# 1

xl2int('Z')
# 26

xl2int('AA')
# 27

xl2int('ZZ')
# 702

xl2int('AAA')
# 703

翻译的工作原理

它移动每个字符,使 A -> 0,B -> 1...J -> 9,K -> A...Z -> P。然后使用 [=12 将其转换为整数=].然而,获得的数字是不正确的,因为我们缺少数字中每个数字位置的 26**x,因此我们添加与输入中的数字一样多的 26 次方。