2011-08-31 105 views
6

将excel样式的列转换为数字(从1开始)是否存在更为pythonic的方式?将Excel或Excel表格列的字母转换为Pythonic风格的数字

工作代码最多两个字母:

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 

参考:question answered in C#

回答

18

有一种方法,使之更加符合Python(作品有三个或三个以上的字母,并使用更少的幻数):

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 

而作为一个班轮使用减少(不检查输入,是不易阅读,所以我不建议这样做):

col2num = lambda col: reduce(lambda x, y: x*26 + y, [ord(c.upper()) - ord('A') + 1 for c in col]) 
+0

你怎么回去的其他方式? –

1

这应该做,在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”)表示,并且应该工作而不管列的长度。

用的,因为你正在做计数的方式三个字母打交道时,你的代码游 - 你需要使用基地26

0

我不知道我的理解正确,你想“翻译“引用的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 
0

只是做:

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 
5

下面是做到这一点的方法之一。这是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 
1

看完这个,我决定找到一种方法,直接在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。

1

使用openpyxl

import openpyxl 
(column_string, row) = openpyxl.cell.coordinate_from_string(address) 
column = openpyxl.cell.column_index_from_string(column_string) 
0

Coincise和优雅红宝石版本:

def col_num(col_name) 
    col_name.split(//).inject(0) { |n, c| n * 26 + c.upcase.ord - "A".ord + 1 } 
end 
+0

这个问题与Ruby无关。 – arogachev

0

对于索引从零开始(例如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())) 
1

我做了这一行:

colNameToNum = lambda cn: sum([((ord(cn[-1-pos]) - 64) * 26 ** pos) for pos in range(len(cn))]) 

它可以通过以相反的顺序字母迭代和1,26,26 * 26等相乘,然后求和名单。这种方法也可以与更长的字母串兼容。

我把它用:

打印(colNameToNum( “AA”))#27

打印(colNameToNum( “XFD”))#允许的最高列,我相信。结果= 16384

0

你可以通过理解和字符串,它是相当容易使用使用oneliner:在Python 2.7.1测试

sum([string.ascii_lowercase.index(c) + 26 ** i for i,c in enumerate(col_letters)]) 
0

一行程序和3.5.2

​​

多套同样

def excel_column_name(n): 
    """Number to Excel-style column name, e.g., 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, e.g., 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) 

所有测试打印

  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 
0

你可以只添加以下到控制台安装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')) 

只要改变字母和数字,以满足您的需求,或者创建一个for循环来了整整做的工作项目。我希望这有帮助。干杯。

相关问题