2013-10-03 15 views
11

Excel-Style Sütun İsim al Bu satır ve sütun kimlik verildiğinde ama row = 1 and col = 104 gibi değerler vermek, bunun CZ dönmelidir zaman SÜTUN adını veren kodudur, ancak [email protected]Sütun sayısı

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 
döndürür

Yaptığım şeyle ilgili sorun nedir?

(Bu kod bir satır, sütun ID değeri sağlar ve aynı alfabetik değer bekliyoruz EXCEL Sütunlar, referans olarak geçmektedir.)

+0

@MartijnPieters bunu biliyorum. Değişken değerlerini int değerleriyle değiştirdim, ancak bu soru reddetmek anlamına gelmiyor. –

+4

Sorunuzda oy kullanmadım. Lütfen yorum yapma ve oylama işleminin aynı şey olduğunu düşünmeyin. –

+1

Sorunuz * biraz belirsizdir, ancak belki de belki de biçimlendirmeye ve dilbilgisine daha fazla düşer. Kod sağladınız, beklenen sonuç ve sonuç gözlemlediniz, ama elde etmeye çalıştığınız şey bana açık değil. –

cevap

14

EDIT: Ben itiraf etmeliyim hissediyorum, birkaç diğerleri-me bırakmadı tarafından işaret olarak yorumlar yani Cevabımın önceki sürümünde (kabul ettiniz), 702 numaralı sütunun ('ZZ' numaralı Excel sütununa karşılık gelen) sütun numaralarını doğru şekilde kullanmasını engelleyen bir hata oluştu. Bu yüzden, doğruluk çıkarları doğrultusunda, aşağıdaki kodda, şu anda diğer cevapların çoğu gibi bir döngü içerdiği tespit edilmiştir.

Büyük olasılıkla, önceki sürümde, sorunla karşılaşmak için yeterince büyük sütun numarası kullanmamışsınızdır. FWIW, MS specs for the current version of Excel, 16,384 adede kadar sütun içeren çalışma sayfalarını desteklediğini söylüyor (Excel sütunu '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))) 

Çıktı: kendi kod sade ve takip edilmesi kolay görünüyor beri

(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' 
0

I o buldum. divmod (104,26), chr (0 + 64) = 64 yani '@' yapan mod = 0 değerini verir.

i ince

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 
1

çalışması gerektiğini düşünüyorum column_label "mod=26 if mod==0 else mod" önce bu satırı ekleyin eğer böyle bir şey olduğunu düşünüyorum:

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

Bazı testler:

>>> 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' 
11

Birkaç dizin sorununuz var:

Yani sorunu çözmek için, kendi endeksleri eşleşen tüm yapmak gerekir :

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 
4

Ben maritineau cevabını seviyorum. Ancak 26 ** 2 + 26'dan büyük olan sütun numarasını tutamaz. Bu yüzden bir parçasını değiştiririm.

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 
0

kullanacağım bu kodu Sonuçlar:

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]) 
0
def ColNum2ColName(n): 
    convertString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    base = 26 
    i = n - 1 

    if i < base: 
     return convertString[i] 
    else: 
     return ColNum2ColName(i//base) + convertString[i%base] 

DÜZENLEME: Tamam, tamam Zondo.

A-Z numaralı rakamlarla A, B, .. AA, AB, ... numaralı sayısal tabana yaklaştım.

A = 1 
B = 2 
. 
. 
X = 24 
Y = 25 
Z = 26 
. 
. 
. 

Herhangi while döngüsü vb olmadan kolay bir yol ve herhangi bir sayı > 0 için çalışır.

+0

Bir tür döngü yerine yinelemeyi kullanıyorsunuz, bu daha basit bir görünüme sahipken, genellikle daha fazla yükü içerecek ve (önemsiz) bir döngü koşulunu kontrol etmekten daha yavaş olacaktır. – martineau