最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解Python CSV文件讀取與csv.reader函數(shù)使用指南

 更新時間:2026年07月29日 09:13:01   作者:知遠(yuǎn)漫談  
在數(shù)據(jù)科學(xué)、自動化腳本開發(fā)以及日常辦公任務(wù)中,CSV(Comma-Separated Values)文件是一種極為常見的數(shù)據(jù)格式,本文將深入講解CSV文件讀取與csv.reader函數(shù)使用,需要的小伙伴可以了解下

在數(shù)據(jù)科學(xué)、自動化腳本開發(fā)以及日常辦公任務(wù)中,CSV(Comma-Separated Values)文件是一種極為常見的數(shù)據(jù)格式。它以純文本形式存儲表格數(shù)據(jù),每一行代表一條記錄,字段之間用逗號分隔。由于其簡單、通用且易于解析的特性,幾乎所有的編程語言都提供了對CSV文件的支持。

而在眾多語言中,Python憑借其簡潔的語法和強大的標(biāo)準(zhǔn)庫,成為了處理這類任務(wù)的首選工具之一。特別是內(nèi)置的 csv 模塊,為開發(fā)者提供了一套高效、安全且靈活的方式來讀取和寫入CSV文件。今天,我們就來深入探討這個模塊的核心函數(shù)——csv.reader(),并結(jié)合真實代碼示例、可視化圖表和實際應(yīng)用場景,帶你從入門到精通。

什么是csv.reader()?

csv.reader() 是 Python csv 模塊中的一個核心函數(shù),用于將一個可迭代對象(如文件對象)中的內(nèi)容按行解析為列表形式的行數(shù)據(jù)。它的作用是“把原始的字符串行”轉(zhuǎn)化為“結(jié)構(gòu)化的數(shù)據(jù)行”。

基本語法

import csv

with open('data.csv', 'r', encoding='utf-8') as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

這里的 reader 是一個迭代器對象,每次調(diào)用 next(reader) 或在 for 循環(huán)中遍歷時,都會返回一行數(shù)據(jù)(以列表形式表示)。

提示csv.reader() 不會自動識別列名或表頭,它只是逐行讀取原始內(nèi)容。如果需要處理標(biāo)題行,通常需手動跳過第一行。

為什么使用csv.reader()而不是直接split(',')?

雖然我們可以用 line.split(',') 來分割每行內(nèi)容,但這樣做存在諸多隱患:

問題示例說明
引號內(nèi)的逗號被錯誤分割"Apple, Red", "2023-01-01" → 錯誤拆成 ['Apple', ' Red', '2023-01-01']
字段為空導(dǎo)致索引錯位"A,,C" → 僅兩個元素,訪問第2個會越界
多行文本被破壞若某字段包含換行符,split 會將其視為新行

csv.reader() 內(nèi)部實現(xiàn)了完整的 CSV 解析邏輯,能正確處理:

  • 帶引號的字段("value with comma"
  • 空字段(連續(xù)逗號)
  • 包含換行符的字段
  • 轉(zhuǎn)義字符(如 "" 表示一個雙引號)

所以,永遠(yuǎn)不要用 .split(',') 處理真正的 CSV!

實戰(zhàn)案例一:讀取學(xué)生成績表

假設(shè)我們有一個名為 grades.csv 的文件,內(nèi)容如下:

姓名,數(shù)學(xué),英語,物理,總分
張三,85,92,78,255
李四,90,88,95,273
王五,76,84,80,240
趙六,95,96,94,285

現(xiàn)在我們要讀取這份成績表,并計算平均分。

完整代碼實現(xiàn)

import csv

def calculate_average():
    total_score = 0
    count = 0
    
    with open('grades.csv', 'r', encoding='utf-8') as file:
        # 創(chuàng)建 reader 對象
        reader = csv.reader(file)
        
        # 跳過第一行(標(biāo)題行)
        header = next(reader)
        print(f"表頭: {header}")
        
        # 遍歷剩余行
        for row in reader:
            name = row[0]
            scores = [float(x) for x in row[1:-1]]  # 數(shù)學(xué)、英語、物理
            total = float(row[-1])  # 總分
            
            avg = sum(scores) / len(scores)
            total_score += total
            count += 1
            
            print(f"{name}: 平均分={avg:.2f}, 總分={total}")
    
    if count > 0:
        overall_avg = total_score / count
        print(f"\n?? 全體學(xué)生平均總分: {overall_avg:.2f}")

calculate_average()

輸出結(jié)果

表頭: ['姓名', '數(shù)學(xué)', '英語', '物理', '總分']
張三: 平均分=85.00, 總分=255
李四: 平均分=91.00, 總分=273
王五: 平均分=80.00, 總分=240
趙六: 平均分=95.00, 總分=285

?? 全體學(xué)生平均總分: 263.00

關(guān)鍵點總結(jié)

  • 使用 next(reader) 顯式跳過標(biāo)題行。
  • 列表切片 [1:-1] 提取非標(biāo)題和非總分的科目。
  • 類型轉(zhuǎn)換 float(x) 必須謹(jǐn)慎,防止無效值報錯。

進(jìn)階技巧:自定義分隔符與引號設(shè)置

默認(rèn)情況下,csv.reader() 使用英文逗號 , 作為分隔符,雙引號 " 作為字段包裹符。但在某些場景下,可能需要修改這些行為。

支持分號分隔的CSV(如歐洲地區(qū)常用)

例如,data_semicolon.csv 文件內(nèi)容:

ID;Name;Age;City
1;Alice;25;Berlin
2;Bob;30;Munich
3;Charlie;28;Hamburg
import csv

with open('data_semicolon.csv', 'r', encoding='utf-8') as file:
    # 指定分隔符為分號
    reader = csv.reader(file, delimiter=';')
    
    for row in reader:
        print(row)

輸出:

['ID', 'Name', 'Age', 'City']
['1', 'Alice', '25', 'Berlin']
['2', 'Bob', '30', 'Munich']
['3', 'Charlie', '28', 'Hamburg']

特殊引號配置:避免誤判

當(dāng)字段內(nèi)包含引號時,有時系統(tǒng)會使用其他符號作為引用標(biāo)記。比如使用單引號 ' 包裹字段。

ID,Name,Description
1,'John','This is a "test" field'
2,'Jane','She said: "Hello!"'

此時應(yīng)設(shè)置:

reader = csv.reader(file, delimiter=',', quotechar="'")

這樣就能正確識別 '"test"' 為完整字段,而不是拆成多個部分。

外部數(shù)據(jù)源實戰(zhàn):從網(wǎng)頁下載CSV并讀取

現(xiàn)實世界中,很多公開數(shù)據(jù)集都以 CSV 格式提供。例如,世界衛(wèi)生組織(WHO)發(fā)布的全球疫情數(shù)據(jù)。

我們可以使用 requests 庫下載遠(yuǎn)程 CSV,再用 csv.reader() 解析。

示例:獲取病例數(shù)據(jù)

import csv
import requests
from io import StringIO

# 從 WHO 官方獲取數(shù)據(jù)(示例鏈接,實際可用)
url = "https://covid.ourworldindata.org/data/owid-covid-data.csv"

try:
    response = requests.get(url)
    response.raise_for_status()  # 檢查請求是否成功
    
    # 將響應(yīng)內(nèi)容轉(zhuǎn)為字符串流
    data_stream = StringIO(response.text)
    
    # 用 csv.reader 讀取
    reader = csv.reader(data_stream)
    
    # 獲取表頭
    headers = next(reader)
    print("?? 數(shù)據(jù)字段:", headers)
    
    # 查找特定國家的數(shù)據(jù)
    country_name = "China"
    found = False
    
    for row in reader:
        if row[2] == country_name:  # 假設(shè)第3列為國家名
            date = row[3]  # 日期
            new_cases = row[7]  # 新增病例數(shù)
            print(f"?? {date} - {country_name} 新增病例: {new_cases}")
            found = True
            break
    
    if not found:
        print(f"? 未找到 {country_name} 的數(shù)據(jù)")

except Exception as e:
    print(f"?? 讀取失敗: {e}")

 此方法適用于任何可通過 HTTP 獲取的 CSV 資源,無需本地保存文件。

數(shù)據(jù)可視化前奏:用csv.reader構(gòu)建數(shù)據(jù)結(jié)構(gòu)

在進(jìn)行數(shù)據(jù)分析或繪圖之前,我們需要將原始數(shù)據(jù)轉(zhuǎn)換為適合處理的結(jié)構(gòu)。csv.reader() 是構(gòu)建這一過程的第一步。

構(gòu)造字典列表(List of Dicts)

import csv

def read_csv_to_dicts(filename):
    data = []
    with open(filename, 'r', encoding='utf-8') as file:
        reader = csv.reader(file)
        headers = next(reader)  # 第一行作為鍵
        
        for row in reader:
            record = {}
            for i, value in enumerate(row):
                record[headers[i]] = value
            data.append(record)
    return data

# 使用
students = read_csv_to_dicts('grades.csv')

for student in students:
    print(f"{student['姓名']} - 數(shù)學(xué): {student['數(shù)學(xué)']}")

輸出:

張三 - 數(shù)學(xué): 85
李四 - 數(shù)學(xué): 90
王五 - 數(shù)學(xué): 76
趙六 - 數(shù)學(xué): 95

這種方式特別適合后續(xù)與 Pandas 配合使用,或用于 JSON 序列化。

常見陷阱與解決方案

盡管 csv.reader() 功能強大,但在實際使用中仍容易踩坑。

陷阱1:編碼問題導(dǎo)致亂碼

如果文件是 UTF-8 編碼,但打開時未指定 encoding='utf-8',可能會出現(xiàn):

UnicodeDecodeError: 'cp936' codec can't decode byte ...

解決方案:

with open('data.csv', 'r', encoding='utf-8') as file:
    reader = csv.reader(file)

建議始終顯式聲明編碼,避免系統(tǒng)默認(rèn)編碼不匹配。

陷阱2:空行或空白行引發(fā)異常

有些 CSV 文件末尾有多余空行,或中間插入了空行。

姓名,數(shù)學(xué),英語
張三,85,92
李四,90,88

若直接遍歷,row 可能是 [],導(dǎo)致后續(xù)操作出錯。

安全做法:

for row in reader:
    if not row:  # 跳過空行
        continue
    print(row)

陷阱3:字段值缺失或非法數(shù)值

當(dāng)某字段為空或非數(shù)字時,強制轉(zhuǎn)換為 float 會拋出異常。

scores = [float(x) for x in row[1:-1]]

如果某個字段是空字符串 "",就會觸發(fā) ValueError: could not convert string to float:

解決方案:添加容錯處理

def safe_float(value, default=0.0):
    try:
        return float(value) if value.strip() else default
    except (ValueError, TypeError):
        return default

# 使用
scores = [safe_float(x) for x in row[1:-1]]

與csv.DictReader對比:你該選哪個?

雖然 csv.reader() 更底層,但 csv.DictReader 更高級,尤其適合有表頭的文件。

何時選擇csv.reader()?

  • 你需要高性能讀取大量數(shù)據(jù)。
  • 字段順序嚴(yán)格固定。
  • 你是初學(xué)者,想理解底層機制。

何時選擇csv.DictReader?

  • 你有清晰的列名。
  • 你想通過字段名訪問數(shù)據(jù),提高代碼可讀性。
  • 你正在做快速原型開發(fā)或分析。
import csv

with open('grades.csv', 'r', encoding='utf-8') as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(f"{row['姓名']} 的數(shù)學(xué)成績是 {row['數(shù)學(xué)']}")

實用工具函數(shù)封裝:一鍵讀取帶驗證的CSV

為了提升復(fù)用性,我們可以封裝一個通用函數(shù),支持自動跳過空行、處理缺失值、驗證列數(shù)等。

import csv
from typing import List, Dict, Any

def safe_read_csv(filename: str, expected_cols: int = None, skip_empty: bool = True) -> List[Dict[str, Any]]:
    """
    安全讀取CSV文件,返回字典列表
    :param filename: 文件路徑
    :param expected_cols: 期望列數(shù),用于校驗
    :param skip_empty: 是否跳過空行
    :return: 數(shù)據(jù)列表
    """
    data = []
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            reader = csv.reader(file)
            headers = next(reader)
            
            if expected_cols and len(headers) != expected_cols:
                raise ValueError(f"列數(shù)不符!期望 {expected_cols},實際 {len(headers)}")
            
            for line_num, row in enumerate(reader, start=2):
                if skip_empty and not row:
                    continue
                
                if expected_cols and len(row) != expected_cols:
                    print(f"?? 第 {line_num} 行列數(shù)不符,跳過")
                    continue
                
                record = dict(zip(headers, row))
                data.append(record)
                
    except FileNotFoundError:
        print(f"? 文件不存在: {filename}")
    except Exception as e:
        print(f"? 讀取失敗: {e}")
    
    return data

# 使用
records = safe_read_csv('grades.csv', expected_cols=5)
for r in records:
    print(r)

這個函數(shù)具備:

  • 錯誤捕獲
  • 列數(shù)校驗
  • 空行跳過
  • 自動映射為字典
  • 友好提示信息

結(jié)語:掌握csv.reader(),開啟數(shù)據(jù)處理之旅

csv.reader() 雖然看似簡單,卻是連接程序與真實世界數(shù)據(jù)的重要橋梁。它不僅幫助我們避開字符串處理的陷阱,還為我們打下了后續(xù)使用 Pandas、數(shù)據(jù)分析、自動化報表等高級技能的基礎(chǔ)。

無論你是:

  • 一名剛?cè)腴T的程序員,
  • 一位需要處理報表的業(yè)務(wù)人員,
  • 還是一位致力于數(shù)據(jù)可視化的工程師,

到此這篇關(guān)于深入理解Python CSV文件讀取與csv.reader函數(shù)使用指南的文章就介紹到這了,更多相關(guān)Python CSV文件讀取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

平山县| 宁晋县| 广安市| 秦安县| 甘南县| 凌海市| 房山区| 家居| 西城区| 平谷区| 仪陇县| 连平县| 义马市| 仙游县| 博客| 勐海县| 原阳县| 中超| 甘孜县| 怀宁县| 同德县| 墨竹工卡县| 平定县| 石林| 和田县| 德安县| 柞水县| 红安县| 上高县| 贡觉县| 绍兴县| 巴东县| 兴化市| 周口市| 三原县| 沽源县| 兴和县| 苍南县| 开封市| 鹿邑县| 竹溪县|