[英]Get the Excel column label (A, B, ..., Z, AA, ..., AZ, BA, ..., ZZ, AAA, AAB, ...)
给定 Excel 列 header 的字母,我需要 output 列号。
它是AZ
,然后是AA-AZ
然后是BA-BZ
等等。
我想通过它 go 就像它是 26 进制一样,我只是不知道如何实现它。
它适用于像AA
这样的简单算法,因为26^0 = 1
+ 26^1 = 26
= 27
。
但是对于像ZA
这样的东西,如果我做26 ^ 26
(z 是第 26 个字母),output 显然太大了。 我错过了什么?
如果我们将“A”解码为 0,“B”解码为 1,……那么“Z”为 25,“AA”为 26。
所以它不是纯 26 基编码,因为前缀“A”对值没有影响,“AAAB”必须与“B”相同,就像十进制系统中 0001 相等到 1. 但这里不是这样。
“AA”的值为 1*26 1 + 0,“ZA”的值为 26*26 1 + 0。
我们可以概括并说“A”的值应该是 1,“B”应该是 2,……等等(除了单个字母编码)。 所以在“AAA”中,最右边的“A”代表系数为0,而其他的“A”代表系数:1*26 2 + 1*26 1 + 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
参数的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。然后它使用int
将其转换为整数。 但是得到的数字是不正确的,因为我们在数字中的每个数字位置都缺少 26**x,所以我们添加了与输入中的数字一样多的 26 的幂。
另一种方法,写在 VBA 中:
Function nColumn(sColumn As String) As Integer
' Return column number for a given column letter.
' 676 = 26^2
' 64 = Asc("A") - 1
nColumn = _
(IIf(Len(sColumn) < 3, 0, Asc(Left( sColumn , 1)) - 64) * 676) + _
(IIf(Len(sColumn) = 1, 0, Asc(Left(Right(sColumn, 2), 1)) - 64) * 26) + _
(Asc( Right(sColumn , 1)) - 64)
End Function
或者您可以直接在工作表中进行:
=(if(len(<clm>) < 3, 0, code(left( <clm> , 1)) - 64) * 676) +
(if(len(<clm>) = 1, 0, code(left(right(<clm>, 2), 1)) - 64) * 26) +
(code( right(<clm> , 1)) - 64)
我还发布了以类似方式完成的逆运算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.