目錄
    Add a header to begin generating the table of contents

    用 Python 把英文字母轉換成數字?ord() 和 chr() 的教學

    用 Python 把英文字母轉換成數字?ord() 和 chr() 的教學
    Share on facebook
    Share on twitter
    Share on linkedin
    Share on whatsapp
    目錄
      Add a header to begin generating the table of contents

      最近面試的時候遇到一個頗容易,但我卻一時三刻不能解答的問題,就是在 Python 裡如何把英文字母以數字的形式表達?

      譬如說我們有像 Excel 試算表的數據,以英文字母代表列(Column): {'A1': 10, 'B1': 30, 'C3': 20}。我們如何把 A1 轉換成 (1, 1),B1 轉換成 (2, 1) 等座標,方便我們使用數字索引(index)?

      ASCII 與英文字母

      如果您曾經學習過一些編程,或者會聽說過 ASCII (美國資訊交換標準代碼)這一個概念。簡單來說,ASCII 是一個國際認受的字元(character)索引(index)。

      上圖顯示 ASCII 索引表的某些數值。留意左邊的數值(46-109)是一個索引(index),而右邊是該索引所指的符號/字元。

      比方說,在 ASCII 索引表的第 63 個符號是「?」。

      我是廣告 ^o^

      我們注意到 ASCII 索引表的第 65 個符號是大寫「A」,而第 97 個符號是小寫「a」。而其他英文字母則以順序排列在 66-90 (大寫)和 98-122(小寫)。

      因此,我們只需要在 ASCII 表找到將所需的英文字母,例如「p」,便可以把所有英文字母以數字形式排列。

      ord():英文字母到數字

      print('a 的 ASCII 索引是', ord('a')) print('A 的 ASCII 索引是', ord('A'))

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      要達到上面提及的要求,在 Python 裡,我們可以使用內置的功能 ord() 獲取一個單字的 ASCII 索引。

      如上面所示,我們輸入 ord('a') 以後,會輸出 97,即英文字母 a 的 ASCII 索引。

      我是廣告 ^o^

      留意 ‘a’ (小寫)和 ‘A’ (大寫)的 ASCII 索引不同,因此我們在處理大小寫時需要小心。

      如果我們需要找到一串英文字母的 ASCII 索引,該如何辦?

      多於一個英文字母的 ord()

      my_str = 'PythonViz' [x + ' 的 ASCII 代碼是 ' + str(ord(x)) for x in my_str]

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      我們當然使用 Python 的好朋友 List Comprehension (按此了解更多)去處理這個情況。如上圖所示,我們可以直接使用 ord(x) for x in my_str 的語法,揉合 List Comprehension 去獲取多個英文字母的 ASCII 索引。

      把英文字母排序

      回到我們原本的問題:如何知道英文字母的排列(如 A -> 1, B -> 2 …)?

      我是廣告 ^o^

      我們最終希望寫出一個 Python 功能。這裡我們先做一些假設:

      • 大寫小寫不重要:英文字母 “P” 和 “p” 的排序是一樣
      • 英文字母從 1 開始:A 代表 1,B 代表 2,如此類推
      • 輸入只有 1 個字母:如輸入 “ab”,程式會顯示錯誤
      • 輸入不是字母時:如輸入 “1”,程式會顯示錯誤
      def alphabet_index(alphabet:str): if len(alphabet) > 1: raise NotImplementedError('請輸入 1 個單字的英文字母') elif alphabet.isupper(): return ord(alphabet) - ord('A') + 1 elif alphabet.islower(): return ord(alphabet) - ord('a') + 1 else: raise NotImplementedError('"' + alphabet + '" 並不是英文字母') # 現在我們試一下不同情況的回傳 for x in ['a','B','1','abcd']: try: print('輸入:', x, '\n輸出:', alphabet_index(x),'\n') except Exception as e: print('輸入:', x, '\n輸出:', e,'\n')

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      我們在上面編寫了一個簡單的 Python 功能 alphabet_index() 處理我們上述的要求。這個編程的結構如下:

      1. if len(alphabet) > 1: 如果我們輸入多於一個字元(例如 ‘abcd’),要求用家改為輸入單一英文字母
      2. elif alphabet.isupper(): 如果用家輸入一個大寫英文字母,回傳這個字母與 “A” 的 ASCII 位置分別
      3. elif alphabet.islower(): 如果用家輸入一個大寫英文字母,回傳這個字母與 “a” 的 ASCII 位置分別
      4. else: 如果用家不是輸入一個英文字母,要求用家改為輸入單一英文字母

      在我們的輸出可見我們成功回傳 “B” 為 2,並正確地要求用家重新輸入 “1” 和 “abcd”。

      將 A1,B2 等換成座標

      最後一個 ord() 功能的是把 A1、B2 格式的座標轉換成 (1,1)、(2,2) 的格式,方便我們使用數字索引進行計算。

      我是廣告 ^o^

      如上圖所示,假如我們使用一個字典(dictionary)儲存這個座標的資料,會是 {'A1': 10, 'B2': 12, 'C4': 15, 'D2': 11}。我們能否把座標變成 (1,1) 的格式?

      coordinates = {'A1': 10, 'B2': 12, 'C4': 15, 'D2': 11} {(ord(k[0])-ord('A')+1,int(k[1])): v for k, v in coordinates.items()}

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      我們可以直接使用 ord(k[0]) - ord('A') + 1 把存於字典的座標 ‘A’ 轉換成 1,‘B’ 轉換成 2 等等。如果我們想在輸出前進一步核實座標,可以考慮重用我們剛才的 alphabet_index() 自訂功能:

      def alphabet_index(alphabet:str): if len(alphabet) > 1: raise NotImplementedError('請輸入 1 個單字的英文字母') elif alphabet.isupper(): return ord(alphabet) - ord('A') + 1 elif alphabet.islower(): return ord(alphabet) - ord('a') + 1 else: raise NotImplementedError('"' + alphabet + '" 並不是英文字母') coordinates = {'A1': 10, 'b2': 12, 'C4': 15, 'd2': 11} print({(alphabet_index(k[0]),int(k[1])): v for k, v in coordinates.items()}) coordinates = {'A1': 10, '#2': 12, 'C4': 15, 'd2': 11} print({(alphabet_index(k[0]),int(k[1])): v for k, v in coordinates.items()})

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      留意我們把 “B” 和 “D” 換成小寫亦能回傳正確的座標。而假如我們輸入了無效的座標(例如 “#1″),亦會回傳錯誤(Error)。

      我是廣告 ^o^

      chr():數字到英文字母

      學會了 ord() 這一個功能後,chr() 就只不過是還原 ord() 的動作而已。簡單來說,chr() 是將 ASCII 索引(index)轉換成 ASCII 字元(character)的功能。

      {x: chr(x) for x in [65,90,97,122]}

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      留意上圖顯示,如果我們輸入 chr(65) 會回傳 ‘a’。這符合我們文初的 ASCII 索引表裡,以 ASCII 65 代表小寫 ‘a’ 的。而英文字母的 ASCII 表索引是從 65 至 90 和 97 至 122 的。

      參考上面的 alphabet_index() 功能,我們也可以寫出類似的的「索引至英文字母」功能。我們先一起看看以下例子:

      def indexToAlphabet(ind: int, upperCase: bool = False): if ind < 1 or ind > 26: raise NotImplementedError('請輸入 1 至 26 之間的整數') if upperCase: return chr(ord('A') + ind - 1) else: return chr(ord('a') + ind - 1) # 現在我們試一下不同情況的回傳 for x in [(1, False), (1, True), (17, True), (27, False)]: try: print('輸入:', x, '\n輸出:', indexToAlphabet(x[0],x[1]),'\n') except Exception as e: print('輸入:', x, '\n輸出:', e,'\n')

      註:先按一下綠色按鈕 “Run” 執行代碼,讓您能在 IPython Shell 看到編程結果!

      我是廣告 ^o^

      這個 indexToAlphabet 有 2 個輸入:索引(例如我們輸入 1 會見到 ‘a’ 或 ‘A’)和大寫(如果輸入 True 會見到 ‘A’)。

      1. 如果輸入的索引小於 1 或大於 26,那麼我們不能回傳一個英文字母,所以我們回傳一個錯誤(Error)
      2. 如果用戶選擇 upperCase = True 便回傳相應的大寫英文字母,否則回傳小寫

      教學完整代碼

      最後送給大家這篇教學的 Google Colab 完整代碼。如果您不懂得使用免安裝又好用的 Google Colab Notebook,記得閱讀這篇教學了:新手 1/3:5 分鐘免安裝學習 Python?Google Colab Notebook 幫緊您!

      結語

      希望大家如果在 Python 面試遇到類似問題時,可以想起 ord()chr() ,成功擄獲面試官的芳心!

      人氣文章

      快讓我學更多

      small_c_popup.png
      想學習 Python 嗎?
      快來訂閱我們的電子報!