将Excel或电子表格列的字母转换为Pythonic的数字
有没有更好的pythonic方式转换excel样式的列到数字(从1开始)?
工作代码最多两个字母:
def column_to_number(c): """Return number corresponding to excel-style column.""" number=-25 for l in c: if not l in string.ascii_letters: return False number+=ord(l.upper())-64+25 return number
代码运行:
>>> column_to_number('2') False >>> column_to_number('A') 1 >>> column_to_number('AB') 28
三个字母不工作。
>>> column_to_number('ABA') 54 >>> column_to_number('AAB') 54
参考: 在C#中回答的问题
有一种方法可以使它更pythonic(与三个或更多的字母和使用较less的魔术数字):
def col2num(col): num = 0 for c in col: if c in string.ascii_letters: num = num * 26 + (ord(c.upper()) - ord('A')) + 1 return num
而作为一个使用减less(不检查input,不太可读,所以我不推荐它):
col2num = lambda col: reduce(lambda x, y: x*26 + y, [ord(c.upper()) - ord('A') + 1 for c in col])
这是一个办法。 它是XlsxWriter模块中代码的变体:
def col_to_num(col_str): """ Convert base26 column string to number. """ expn = 0 col_num = 0 for char in reversed(col_str): col_num += (ord(char) - ord('A') + 1) * (26 ** expn) expn += 1 return col_num >>> col_to_num('A') 1 >>> col_to_num('AB') 28 >>> col_to_num('ABA') 729 >>> col_to_num('AAB') 704
这应该在VBA中,你正在寻找什么:
Function columnNumber(colLetter As String) As Integer Dim colNumber As Integer Dim i As Integer colLetter = UCase(colLetter) colNumber = 0 For i = 1 To Len(colLetter) colNumber = colNumber + (Asc(Mid(colLetter, Len(colLetter) - i + 1, 1)) - 64) * 26 ^ (i - 1) Next columnNumber = colNumber End Function
您可以像使用Excel公式一样使用它 – 以字母(例如,“AA”)的字母input列,并且应该可以工作,而不pipe列的长度。
你的代码在处理三个字母的时候会因为你计算的方式而中断 – 你需要使用基数26。
读完这个之后,我决定find一种直接在Excel单元格中完成的方法。 它甚至占Z之后的列。
只需将此公式粘贴到任何列的任意行的单元格中,它就会给出相应的编号。
=IF(LEN(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))=2, CODE(LEFT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1))-64*26)+ CODE(RIGHT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1)-64), CODE(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))-64)
这里的主题是抓住列的字母,得到它的Code()
并减去64,基于字母A
的ASCII字符代码是64。
使用openpyxl
import openpyxl (column_string, row) = openpyxl.cell.coordinate_from_string(address) column = openpyxl.cell.column_index_from_string(column_string)
我做了这一行:
colNameToNum = lambda cn: sum([((ord(cn[-1-pos]) - 64) * 26 ** pos) for pos in range(len(cn))])
它通过以相反的顺序遍历字母并乘以1,26,26 * 26等工作,然后求和列表。 这种方法也可以与更长的string兼容。
我打电话给:
打印(colNameToNum(“AA”))#27
要么
print(colNameToNum(“XFD”))#允许的最高列,我相信。 结果= 16384
我不确定我是否理解正确,你是否想将所引用的C#代码“翻译”为python? 如果是这样,你是在正确的轨道上; 只需修改它:
def column_to_number(c): """Return number corresponding to excel-style column.""" sum = 0 for l in c: if not l in string.ascii_letters: return False sum*=26 sum+=ord(l.upper())-64 return sum
做就是了 :
print ws.Range("E2").Column
通话示例:
from win32com import client xl = client.Dispatch("Excel.Application") wb = xl.Workbooks.Open("c:/somePath/file.xls") xl.Visible = 1 ws = wb.Sheets("sheet 1") print ws.Range("E2").Column
结果:
>>5
简洁而优雅的Ruby版本:
def col_num(col_name) col_name.split(//).inject(0) { |n, c| n * 26 + c.upcase.ord - "A".ord + 1 } end
对于从零开始的索引(例如,A = 0,B = 1等等):
def col_to_index(col): A = ord('A') return sum(i * 26 + (ord(c) - A) for i, c in enumerate(col[::-1].upper()))
你可以使用这个简单易懂的理解和string:
sum([string.ascii_lowercase.index(c) + 26 ** i for i,c in enumerate(col_letters)])
单行testingPython 2.7.1和3.5.2
excel_col_num = lambda a: 0 if a == '' else 1 + ord(a[-1]) - ord('A') + 26 * excel_col_num(a[:-1]) excel_col_name = lambda n: '' if n <= 0 else excel_col_name((n - 1) // 26) + chr((n - 1) % 26 + ord('A'))
多内衬也是如此
def excel_column_name(n): """Number to Excel-style column name, eg, 1 = A, 26 = Z, 27 = AA, 703 = AAA.""" name = '' while n > 0: n, r = divmod (n - 1, 26) name = chr(r + ord('A')) + name return name def excel_column_number(name): """Excel-style column name to number, eg, A = 1, Z = 26, AA = 27, AAA = 703.""" n = 0 for c in name: n = n * 26 + 1 + ord(c) - ord('A') return n def test (name, number): for n in [0, 1, 2, 3, 24, 25, 26, 27, 702, 703, 704, 2708874, 1110829947]: a = name(n) n2 = number(a) a2 = name(n2) print ("%10d %-9s %s" % (n, a, "ok" if a == a2 and n == n2 else "error %d %s" % (n2, a2))) test (excel_column_name, excel_column_number) test (excel_col_name, excel_col_num)
所有testing打印
0 ok 1 A ok 2 B ok 3 C ok 24 X ok 25 Y ok 26 Z ok 27 AA ok 702 ZZ ok 703 AAA ok 704 AAB ok 2708874 EXCEL ok 1110829947 COLUMNS ok
安装openpyxl模块后,您可以将以下内容添加到控制台:
import openpyxl from openpyxl.utils import get_column_letter, column_index_from_string workbook = openpyxl.load_workbook('your_workbook.xlsx') sheet = wb.get_sheet_by_name('your_sheet_from_workbook') print(get_column_letter(1)) print(column_index_from_string('A'))
只需更改字母和数字以满足您的需求,或创build一个for-loop来完成整个项目的工作。 我希望这有帮助。 干杯。