2011-08-31 60 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循環來了整整做的工作項目。我希望這有幫助。乾杯。

相關問題