2011-08-31 36 views
6

Có cách nào khác để chuyển đổi các cột kiểu excel thành số (bắt đầu bằng 1) không?Chuyển đổi chữ cái excel hoặc bảng tính thành số của nó theo kiểu Pythonic

Làm việc mã lên đến hai chữ:

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 

Mã chạy:

>>> column_to_number('2') 
False 
>>> column_to_number('A') 
1 
>>> column_to_number('AB') 
28 

Ba chữ không làm việc.

>>> column_to_number('ABA') 
54 
>>> column_to_number('AAB') 
54 

tham khảo: question answered in C#

Trả lời

18

Có một cách để làm cho nó pythonic hơn (chỉ hoạt động với ba hoặc nhiều chữ cái và sử dụng số ít ma thuật):

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 

Và như một lớp lót bằng giảm (không kiểm tra đầu vào và ít có thể đọc được vì vậy tôi không khuyên bạn nên nó):

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

Và làm thế nào để bạn quay trở lại theo cách khác? –

1

này nên làm, trong VBA, những gì bạn đang tìm kiếm:

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 

Bạn có thể sử dụng nó như bạn sẽ một công thức Excel - nhập cột, bằng chữ cái, dưới dạng chuỗi (ví dụ: "AA") và sẽ hoạt động bất kể chiều dài cột.

đang nghỉ giải lao của bạn khi giao dịch với ba chữ vì cách bạn đang làm việc tính - bạn cần phải sử dụng cơ sở 26.

0

Tôi không chắc là tôi hiểu đúng, bạn có muốn "dịch "mã C# được tham chiếu đến python? Nếu vậy, bạn đã đi đúng hướng; chỉ sửa đổi nó như vậy:

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

chỉ làm:

print ws.Range("E2").Column 

gọi Ví dụ:

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 

kết quả:

>>5 
5

Dưới đây là một cách để làm điều đó. Đây là biến thể trên mã trong mô-đun 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

Sau khi đọc xong, tôi quyết định tìm cách thực hiện trực tiếp trong các ô Excel. Nó thậm chí còn chiếm các cột sau khi Z.

Chỉ cần dán công thức này vào ô của bất kỳ hàng nào của bất kỳ cột nào và nó sẽ cung cấp cho bạn số tương ứng.

=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) 

Các chủ đề ở đây là để lấy lá thư của cột, có Code() của nó và trừ 64, dựa trên thực tế rằng mã ký tự ASCII cho thư A là 64.

1

Sử dụng openpyxl

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

Coincise và thanh lịch của Ruby phiên bản:

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

Câu hỏi không liên quan gì đến Ruby. – arogachev

0

Đối với chỉ số bắt đầu từ con số không (ví dụ A = 0, B = 1, và vân vân):

def col_to_index(col): 
    A = ord('A') 
    return sum(i * 26 + (ord(c) - A) for i, c in enumerate(col[::-1].upper())) 
1

Tôi đã làm một lớp lót này:

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

Nó hoạt động bằng cách lặp qua các chữ cái theo thứ tự ngược lại và nhân với 1, 26, 26 * 26 vv, sau đó tổng hợp danh sách. Phương pháp này sẽ tương thích với các chuỗi ký tự dài hơn.

Tôi gọi nó với:

in (colNameToNum ("AA")) # 27

hoặc

in (colNameToNum ("XFD")) # cho phép cột cao nhất, tôi tin rằng . Result = 16384

0

Bạn có thể sử dụng oneliner này sử dụng sự hiểu biết và chuỗi đó là khá dễ dàng để sử dụng:

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

One-lót thử nghiệm bằng Python 2.7.1 và 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')) 

multi-lót tương tự như vậy

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) 

Tất cả các thử nghiệm in

  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

Bạn chỉ có thể thêm dòng sau vào giao diện điều khiển sau khi cài đặt các module 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')) 

Chỉ cần thay đổi các chữ cái và số cho phù hợp với nhu cầu của bạn hoặc tạo cho vòng lặp để thực hiện công việc cho một tổng thể dự án. Tôi hi vọng cái này giúp được. Chúc mừng.

Các vấn đề liên quan