这是在提供行和列ID时提供COLUMN名称的代码,但是当我提供row = 1 and col = 104
之类的值时,它应返回CZ
,但它返回D@
< / p>
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 Columns,其中我提供了Row,Column ID值并期望ALPHABETIC值相同。)
答案 0 :(得分:20)
702
(对应于Excel列'ZZ'
)。因此,为了正确起见,已经在下面的代码中修复了这个问题,现在它包含了一个循环,就像许多其他答案一样。
您很可能从未使用过时版本的大量列号来遇到问题。 FWIW,MS specs for the current version of Excel表示它支持最多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'
答案 1 :(得分:12)
您有几个索引问题:
因此,要解决您的问题,您需要使所有索引匹配:
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
答案 2 :(得分:7)
我喜欢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
答案 3 :(得分:2)
def ColNum2ColName(n):
convertString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
base = 26
i = n - 1
if i < base:
return convertString[i]
else:
return ColNum2ColName(i//base) + convertString[i%base]
编辑:右,右通道。
我刚接触A, B, .. AA, AB, ...
作为数字基数A-Z
。
A = 1
B = 2
.
.
X = 24
Y = 25
Z = 26
.
.
.
这是一种简单的方法,没有任何while循环等,适用于任何数字> 0
。
答案 4 :(得分:1)
我认为是这样的:
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))
一些测试:
>>> 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'
答案 5 :(得分:0)
我想我明白了。 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
答案 6 :(得分:0)
使用此代码:
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])
答案 7 :(得分:0)
这是使用pandas multiindex数据框而无循环获取excel列名的另一种方法。这是对通用基到基转换器的修改,因此代码比其他一些选项更长一些,但我认为它是有效的:
def xlcolumn(num):
base = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
baseln = len(base)
idx = [""]+base
num = num-1
# create pandas multiindex using idx, base
# current excel version has 16384 columns (A --> XFD), so multiindex needs to have a minimum of 3 levels:
# (26x26x26 = 17576 > 16384 columns)
index = pd.MultiIndex.from_product([idx, idx, idx],names=['level 1', 'level 2', 'level 3'])
df = pd.DataFrame(index = index)
df = df.drop("",level = 'level 3')
df = df.iloc[:baseln].append(df.drop("",level = 'level 2'))
df['val']=1
if num < baseln:
xlcol = str(df.iloc[num].name[2])
elif num >= baseln and num < baseln**2:
xlcol = str(df.iloc[num].name[1])+str(df.iloc[num].name[2])
else:
xlcol = str(df.iloc[num].name[0])+str(df.iloc[num].name[1])+str(df.iloc[num].name[2])
return xlcol