在程式設計的世界裡,與用戶互動是建立實用且動態應用程式的關鍵。如果一個程式只能執行預設好的指令,卻無法接收來自外界的即時資訊,那麼它的功能將會受到極大的限制。Python 提供了 input() 函數,這座橋梁讓我們的程式能夠聆聽用戶的聲音,接收來自鍵盤的輸入,從而實現真正的互動性。
無論是編寫一個簡單的計算機、一個複雜的資料分析工具,還是一個線上競賽的解題程式,掌握 input() 的用法都是不可或缺的基礎技能。本文章將從最基礎的語法出發,分享一些關於input()的深入想法,深入探討其核心特性、資料轉換的必要性、處理多重輸入的技巧,並涵蓋錯誤處理與線上解題的進階應用,旨在為您提供一份關於 input() 函數的完整學習地圖。
input() 的基礎核心
基本語法與提示訊息
input() 函數的基本用法極其簡單,其主要作用是暫停程式的執行,等待使用者輸入一行文字,並在用戶按下 Enter 鍵後,將輸入的內容的 值回傳。
最基本的形式不包含任何參數,例如 a=input() 和 b=input():
# 程式會在這裡停下,等待用戶輸入
user_data = input()
print(f"您剛剛輸入的是:{user_data}")
為了讓用戶清楚知道程式正在等待什麼樣的資訊,我們可以在 input() 的括號中加入一個字串作為「提示訊息 (prompt)」。這個提示訊息會先被顯示在螢幕上,然後再等待用戶輸入。
# 顯示提示訊息,讓用戶介面更友善
name = input("請輸入您的姓名(名字):")
print(f"您好,{name}!歡迎來到 Python 的世界。")
- 隱性輸入:不提供提示訊息,如 input()。
- 顯性輸入:提供提示訊息,如 input(“提示文字”),這是推薦的做法,因為它能提升程式的可用性。
關鍵特性:永遠返回字串 (String)
這是學習 input() 時最重要,也最容易被新手忽略的核心觀念:無論用戶輸入的內容看起來像什麼,input() 函數一律將其視為「字串 (str)」類型並回傳。 即使用戶輸入False,它仍然是一個字串’False’,而不是布林值False。
我們可以透過 type() 函數來驗證這一點:
age_input = input("請輸入您的年齡:")
print(f"您輸入的內容是:{age_input}")
print(f"回傳的資料類型是:{type(age_input)}")
執行結果:
請輸入您的年齡:25
您輸入的內容是:25
回傳的資料類型是:<class 'str'>
即使我們輸入了數字 25,它在 Python 內部也被當作字串 ’25’ 來處理。這個特性會直接影響後續的運算。如果我們忘記這點,試圖直接對輸入的「數字」進行數學計算,將會得到意想不到的結果:
# 錯誤示範
num_str = input("請輸入一個數字:")
result = num_str * 2
print(f"結果是:{result}")
執行結果:
請輸入一個數字:10
結果是:1010
這裡的 * 2 並沒有執行數學上的乘以 2,而是執行了字串的「重複」操作,將字串 ’10’ 重複了兩次,變成了 ‘1010’。
資料類型轉換:讓輸入變得有用
為了能對用戶輸入的數字進行正確的數學運算,我們必須手動將 input() 回傳的字串轉換成所需的數值類型。
轉換為數值:int() 與 float()
- int(): 將字串轉換為「整數 (integer)」。
- float(): 將字串轉換為「浮點數 (float)」,也就是包含小數的數字。
通常,為了讓程式碼更簡潔,我們會將 input() 和類型轉換寫在同一行。
轉換為整數 int():
age = int(input("請輸入您的年齡:"))
# 上面這行程式碼中,age是一個 a int 變數
next_year_age = age + 1
print(f"明年您將是 {next_year_age} 歲。")
轉換為浮點數 float()(例如,計算 BMI):
height_m = float(input("請輸入您的身高(公尺):"))
weight_kg = float(input("請輸入您的體重(公斤):")) # 像這行 num2=float(input(...)) 的使用方法很常見
# BMI 公式 = 體重 / (身高 * 身高)
bmi = weight_kg / (height_m ** 2)
# 使用 f-string 進行字串插值,格式化輸出到小數點後兩位
print(f"您的 BMI 指數為:{bmi:.2f}")
健壯的程式碼:使用 try-except 處理錯誤
如果用戶輸入的內容無法被成功轉換為數字(例如,輸入了英文字母),程式將會觸發一個 ValueError 錯誤並立即終止,其追蹤訊息中常會看到most recent call last的字樣。
# 當用戶輸入 'abc' 時,錯誤訊息會指出問題發生在 line 1 或程式碼的某一行
age = int(input("請輸入您的年齡:"))
# ValueError: invalid literal for int() with base 10: 'abc'
一個健壯的程式應該能夠預見並處理這種情況。我們可以使用try-except語句的這種使用方法來捕捉這個錯誤,並給予用戶友善的提示,而不是讓程式崩潰。
try:
age = int(input("請再次輸入您的年齡:"))
print(f"明年您將是 {age + 1} 歲。")
except ValueError:
print("輸入無效,請確保您輸入的是阿拉伯數字。")
透過這種方式,即使發生錯誤,程式也能優雅地處理,並繼續執行或給予指引,大幅提升了用戶體驗。
處理多重輸入:一次讀取多個值
在許多場景下,我們需要用戶在同一行內輸入多個資訊,例如用空格或逗號分隔的數字。這時就需要結合字串的 split() 方法。
使用 split() 分割字串
split() 方法可以根據指定的sep分隔符將一個字串切割成一個包含多個子字串的「串列 (list)」。如果沒有指定分隔符,它預設會使用空白字元(如空格、Tab、換行)來分割。
# 預設以空格分割
user_words = input("請輸入多個詞,以空格分隔:").split()
print(user_words)
# 輸入:hello world python
# 輸出:['hello', 'world', 'python']
# 以逗號分割
user_numbers_str = input("請輸入多個數字,以逗號分隔:").split(',')
print(user_numbers_str)
# 輸入:10,20,30
# 輸出:['10', '20', '30']
結合 map() 實現高效轉換
當我們得到一個包含數字字串的串列後,需要將其中裡面的每一個元素都轉換成數值類型。雖然可以使用 for 迴圈來逐一轉換,但更高效、更具 Python 風格的手段是使用map()函數。
map(function, iterable) 會將一個函式(例如 int 或 float)應用到一個可迭代物件(例如串列)的每一個元素上。
讀取一行固定數量的整數至不同變數:
# 用戶輸入 "25 80"
a, b = map(int, input("請輸入兩個數字,以空格分隔:").split())
# 例如此處的 a 是 25,b 是 80,如果還要加上 b=5,則總和會改變
print(f"兩數相加結果為:{a + b}") # 輸出: 105
讀取一行未知數量的數字至串列:
map() 會回傳一個 map 物件,我們需要用 list() 將其轉換為串列。
numbers = list(map(int, input("請輸入一串數字,以空格分隔:").split()))
total = sum(numbers) # 假設第一個數字是 num1,則 total=num1+...
print(f"輸入的數字串列為:{numbers}")
print(f"所有數字的總和為:{total}")
使用「串列生成式」
串列生成式 (List Comprehension) 是另一種功能強大且簡潔的方法,可以達到與 map() 類似的效果,可讀性也很高。
# 使用串列生成式讀取一串以逗號分隔的數字
numbers = [int(i) for i in input("請輸入數字,以逗號分隔:").split(',')]
print(f"總和為:{sum(numbers)}")
Python input() 常用模式速查表
下表總結了處理各種輸入情境的常用程式碼模式:
需求 (Requirement) | 程式碼範例 (Code Example) | 說明 (Explanation) |
---|---|---|
讀取單一行字串 | s = input(“提示訊息:”) | 最基礎的用法,回傳一個字串。 |
讀取單一整數 | n = int(input(“請輸入整數:”)) | 結合 int() 進行類型轉換。 |
讀取單一浮點數 | f = float(input(“請輸入數字:”)) | 結合 float(),適用於可能有小數的情況。 |
讀取一行由空格分隔的多個項目至串列 (字串) | items = input().split() | 使用 split() 方法將輸入切割成字串串列。 |
讀取一行由空格分隔的多個數字至串列 (整數) | nums = list(map(int, input().split())) | 結合 map 和 list,高效轉換為數字串列。 |
nums = [int(i) for i in input().split()] | 使用串列生成式,效果相同,可讀性佳。 | |
讀取一行固定數量的整數至不同變數 | x, y, z = map(int, input().split()) | map 後直接解包 (unpack) 到對應數量的變數。 |
處理未知數量的測試資料 (EOF) | while True: try: line=input() except EOFError: break | 用於 Online Judge,讀取到檔案結尾 (End-of-File) 為止。 |
進階應用與競賽技巧
處理多筆測資 (EOF)
在參加程式設計競賽(如 ZeroJudge、APCS)時,題目經常要求處理「多筆輸入資料」,但不會明確告知有幾筆。這時需要程式能一直讀取輸入,直到沒有任何輸入為止(即讀到 EOF,End-of-File)。在 Python 中,input() 在讀到 EOF 時會觸發 EOFError。我們可以利用 try-except 來捕捉這個錯誤並結束迴圈。
# 此模板為線上解題系統常用
lines = []
while True:
try:
# 在這裡放置處理每一行輸入的程式碼
line = input()
lines.append(line)
except EOFError:
# 當沒有更多輸入時,會觸發 EOFError,此時跳出迴圈
break
# 迴圈結束後,可以統一處理收集到的所有輸入
# print("所有輸入內容:", lines)
提升輸入速度:sys.stdin.readline()
對於極度要求執行效率的競賽題目,大量的 input() 操作可能會因為效能問題而導致超時。在這種情況下,可以使用 sys 模組中的 stdin.readline() 來替代 input()。readline() 的速度更快,因為它的緩衝區機制更高效。
import sys
# 讀取一行,速度比 input() 快
# 注意:readline() 會連同結尾的換行符 '\n' 一起讀入
line = sys.stdin.readline()
# 因此通常需要搭配 .strip() 或 .rstrip() 去除換行符
clean_line = line.strip()
使用時機:
- input(): 絕大多數日常開發、教學和非極限效能競賽的首選,語法簡潔、直觀。
- sys.stdin.readline(): 僅在處理海量輸入資料、對執行時間有嚴苛要求的競賽場景下使用。
常見問題 (FAQ)
Q1: 為什麼我用 input() 輸入數字後不能直接相加?
A1: 因為 input() 函數的回傳值永遠是字串 (str) 類型。例如,輸入 5 和 5,您得到的是字串 ‘5’ 和 ‘5’,使用 + 號會執行字串串接,得到 ’55’。您必須使用 int() 或 float() 將它們轉換為數字後才能進行數學運算,如 int(‘5’) + int(‘5’) 結果才是 10。
Q2: 如果用戶輸入的不是我預期的數字,程式就壞了怎麼辦?
A2: 這是 ValueError 的典型場景。您應該使用 try…except ValueError 區塊將可能出錯的 int() 或 float() 轉換程式碼包起來。在 except 區塊中,您可以提示用戶輸入無效並顯示錯誤訊息,並要求重新輸入,從而避免程式崩潰。
Q3: input() 和 sys.stdin.readline() 有什麼不同?我該用哪個?
A3: 主要差異在於效能和便利性。input() 方便易用,會自動去除結尾的換行符,適用於絕大多數情況。sys.stdin.readline() 速度更快,但在讀取時會包含結尾的換行符 (\n),需要手動用 .strip() 清理。一般開發請使用 input();只有在處理極大量資料且對執行時間有嚴格限制的程式競賽中,才需要考慮 sys.stdin.readline()。
Q4: 如何在一行內輸入多個用逗號分隔的數字?
A4: 您可以在 split() 方法中指定分隔符為逗號。例如:numbers = [int(i) for i in input().split(‘,’)]。這行程式碼會讀取一行輸入,用逗號將其分割,然後將每個部分轉換為整數,最後存入一個串列。
Q5: eval(input()) 聽起來很方便,為什麼不建議使用?
A5: eval() 函數會將傳入的字串當作 Python 程式碼來執行,這帶來了巨大的安全風險。如果一個惡意用戶輸入了有害的程式碼(例如 os.system(‘rm -rf /’)),eval() 將會不加分辨地執行它,可能導致刪除檔案、竊取資料等嚴重後果。因此,除非您完全確定輸入來源是絕對安全的,否則應絕對避免使用 eval(input()),而是選擇 int()、float() 等更安全的顯式類型轉換方法。
總結
input() 函數是 Python 中實現人機互動的基石。雖然語法簡單,但其背後的運作原理和衍生出的多樣化應用模式,構成了 Python 學習路上一個重要的知識體系。
從本文的探討中,我們可以歸納出幾個核心要點:
- 返回類型:input() 始終回傳字串,類型轉換是處理數值輸入的必經之路。
- 多重輸入:split() 方法是處理單行多個值的關鍵,能靈活應對以空格、逗號等符號分隔的輸入。
- 高效轉換:map() 函數和串列生成式是將多個字串輸入轉換為數值串列的 Pythonic 方式。
- 健壯性:try-except 是處理潛在 ValueError 的標準做法,能防止程式因非法輸入而崩潰。
- 進階場景:在程式競賽等特殊環境下,需要掌握如 EOF 處理和使用 sys.stdin.readline() 等進階技巧。
徹底理解並熟練運用這些模式,不僅能讓您輕鬆應對各種資料輸入的需求,更是從「能寫程式」邁向「寫好程式」的關鍵一步。