عمومیکسب و کار برتر

نحوه کار با فایل csv در پایتون|خواندن و نوشتن csv در پایتون

مقدمه

CSV فایلی است که در آن داده های متنی به صورت جداول منظم در کنار هم دیگر قرار می گیرند. می توان این دسته از فایل ها را در برنامه های مختلفی مانند مایکروسافت آفیس، Google Spreadsheets و یا Libreoffice Calc مشاهده کرد.

نوشتن در فایل های CSV

ابتدا یک فایل جدید پایتونی ایجاد کرده و ماژول CSV را در آن import کنید:

import csv

در ماژول csv می توانید شاهد متدهایی باشید که برای خواندن و ویرایش فایل های csv استفاده می شود. ما در ادامه قصد داریم این متدها را برای کارهایی که می خواهیم انجام دهیم بررسی کنیم.

برای ایجاد یک فایل CSV اولین کاری که باید بکنیم نام گذاری آن است، ما این کار را از طریق یک متغیر ساده انجام خواهیم داد. کار بعدی قرار دادن یکسری header و data برای فایل csv است که ما آن را از طریق لیست و tuple انجام خواهیم داد:

filename = “imdb_top_4.csv”header = (“Rank”, “Rating”, “Title”)data = [(1, 9.2, “The Shawshank Redemption(1994)”),(2, 9.2, “The Godfather(1972)”),(3, 9, “The Godfather: Part II(1974)”),(4, 8.9, “Pulp Fiction(1994)”)]

حال نیاز است تا یک تابع جدید با ورودی های filename، header و data ایجاد کنیم:

def writer(header, data, filename):  pass

برای ایجاد و نوشتن یک فایل جدید نیاز است تا از متد writer که مربوط به ماژول csv می شود استفاده کنیم. برای ایجاد ستون جدید متد writerow را در اختیار داریم که قرار است در ردیف اول ستون های مورد نظر را ایجاد کرده و در ردیف های بعدی نیز لیست data را قرار دهد:

def writer(header, data, filename):  with open (filename, “w”, newline = “”) as csvfile:    movies = csv.writer(csvfile)    movies.writerow(header)    for x in data:      movies.writerow(x)

حال اگر برنامه را اجرا کنید در مسیر پیش فرض یک فایل جدید را مشاهده خواهید کرد. خروجی این فایل باید به صورت زیر باشد:

بروزرسانی و ایجاد تغییرات در فایل CSV

برای ویرایش فایل csv یک تابع جدید با یک پارامتر (نام فایل) را ایجاد خواهیم کرد:

def updater(filename):    with open(filename, newline= “”) as file:        readData = [row for row in csv.DictReader(file)]        # print(readData)        readData[0][‘Rating’] = ‘9.4’        # print(readData)     readHeader = readData[0].keys()    writer(readHeader, readData, filename, “update”)

این تابع ابتدا فایل مورد نظر را دریافت کرده و سپس متن آن را در حالت خواندن به متغیر readData اضافه می کند. در قسمت بعدی باید دیتا قبلی فراخوانی شده و با مقدار جدید جایگزین شود.

آخرین مرحله نیز فراخوانی دوباره تابع writer برای اعمال تغییرات است.

البته در نظر داشته باشید که برای بروزرسانی نیاز است تا آرگومان جدیدی را به تابع writer اضافه کنید. به همین دلیل است که در قطعه کد بالا رشته update به تابع writer اضافه شده است. برای انجام چنین کاری تنها کافی ست در زمان تعریف تابع writer ورودی option را به صورت زیر اضافه کنید:

def writer(header, data, filename, option):

حال باید روی بخش option کنترل داشته باشیم. چراکه نسبت به write و update نیاز است تا واکنش های متفاوتی داشته باشد.

برای انجام چنین کاری یک شرط را به تابع اصلی یعنی writer اضافه می کنیم:

def writer(header, data, filename, option):        with open (filename, “w”, newline = “”) as csvfile:            if option == “write”:                 movies = csv.writer(csvfile)                movies.writerow(header)                for x in data:                    movies.writerow(x)            elif option == “update”:                writer = csv.DictWriter(csvfile, fieldnames = header)                writer.writeheader()                writer.writerows(data)            else:                print(“Option is not known”)

شکل کدهای شما تا این بخش از مطلب باید به صورت زیر باشد:

در پایان

پایتون و مفاهیم realpython یکی از منعطف ترین زبان های برنامه نویسی برای کار با دیتا های مختلف است. CSV نیز یکی از موارد بسیار مهم در بین قالب های مختلف داده ای ست که به لطف ماژول CSV به سادگی می توانیم با آن تعامل برقرار کنیم.

برای کار کردن با فایل های csv در پایتون، ابتدا لازم است ماژول csv را ایمپورت کنید:

import csv

سپس با متد open پایتون فایل csv موردنظر را در حالت خواندن(r) باز میکنیم:

with open(‘persons.csv’, ‘r’) as csvfile:

        data = csv.reader(csvfile)

        for line in data:

               print(line)

در قطعه کد بالا بعد از بازکردن فایل با متد open، آن فایل را به تابع reader از ماژول csv ارسال میکنیم. سپس میتوانیم اطلاعات داخل فایل را با یک حلقه for نمایش دهیم. بعد از اجرای کد بالا نتیجه زیر را میگیریم:

[‘name’, ‘age’, ’email’]

[‘amir’, ’15’, ‘amir@gmail.com’]

[‘jack’, ’38’, ‘jack@email.com’]

ماژول csv پایتون اطلاعات خوانده شده از فایل را به شکل لیست نمایش میدهد. دقت کنید که اولین خط نام ستونهایی است که اطلاعات را در آنها ذخیره کرده ایم.

پایتون کلاس دیگری به نام DictReader دارد که اطلاعات فایل csv را به شکل دیکشنری نمایش میدهد. برای استفاده از این کلاس کافیست آن را جایگزین reader کنید:

with open(‘persons.csv’, ‘r’) as csvfile:

        data = csv.DictReader(csvfile)

        for line in data:

               print(line)

اگر کد بالا را اجرا کنید اطلاعات را به شکل دیکشنری به دست می آورید:

{‘name’: ‘amir’, ‘age’: ’15’, ’email’: ‘amir@gmail.com’}

{‘name’: ‘jack’, ‘age’: ’38’, ’email’: ‘jack@email.com’}

نوشتن فایل های csv در پایتون

برای نوشتن اطلاعات در فایل های csv با استفاده از پایتون میتوانید از تابع writer استفاده کنید. تابع writer اطلاعات ورودی را به شکل لیست گرفته و در فایل csv مینویسد. به مثال زیر دقت کنید:

with open(‘persons.csv’, ‘w’) as csvfile:

        data = csv.writer(csvfile)

        data.writerow([‘name’, ‘age’, ’email’])

        data.writerow([‘amir’, 12, ‘amir@email.com’])

        data.writerow([‘jack’, 35, ‘jack@email.com’])

برای نوشتن در فایل های csv ابتدا یک فایل با تابع open باز میکنید. اگر فایل از قبل وجود داشته باشد، اطلاعات در آن بازنویسی خواهد شد اما اگر فایل وجود نداشته باشد، آن را ایجاد میکند.

سپس فایل باز شده را به تابع writer ماژول csv میدهیم. در مرحله بعد با تابع writerow میتوانید مقادیر را به شکل لیست ارسال کرده و در فایل csv بنویسید. اگر قطعه کد بالا را اجرا کنید فایلی با نام persons.csv ایجاد خواهد شد که محتویات زیر را دارد:

name,age,email

amir,12,amir@email.com

jack,35,jack@email.com

همانطور که مشخص است اطلاعات با کاما از یکدیگر جدا شده اند. اما میتوانید با پارامتر delimiter نوع جداکننده را تغییر دهید:

data = csv.writer(csvfile, delimiter=’-‘)

برای نوشتن در فایل های csv کلاس دیگری وجود دارد به نام DictWriter که اطلاعات را به شکل دیکشنری گرفته و در فایل وارد میکند. در این کلاس حتما باید نام فیلدها را جداگانه مشخص کنید. به مثال زیر دقت کنید:

with open(‘persons.csv’, ‘w’) as csvfile:

        data = csv.DictWriter(csvfile, fieldnames=[‘name’, ‘age’, ’email’])

        data.writeheader()

        data.writerow({‘name’:’amir’, ‘age’:12, ’email’:’amir@email.com’})

        data.writerow({‘name’:’jack’, ‘age’:25, ’email’:’jack@email.com’})

در کد بالا از کلاس DictWriter برای نوشتن در فایل csv استفاده کردیم. این کلاس ابتدا فایل باز شده و سپس نام فیلدها را میگیرد. در مرحله بعد با متد writeheader نام فیلدها را در خط اول فایل csv مینویسیم. بعد با تابع writerow دوباره اطلاعات را در فایل csv خط به خط مینویسیم با این تفاوت که این بار باید اطلاعات را به شکل دیکشنری ارسال کنید

قصد داریم برنامه ای نوشته که از داخل یک فایل CSV، اطلاعات چند دانشجو که شامل نام و نمرات آزمون های آنها است را خوانده و در فایل CSV دیگری، نام و معدل نمرات آن ها را ذخیره کند.

اطلاعات ورودی ما در یک فایل با فرمت csv ذخیره شده است. فایل csv یا Comma Separeted Values به معنای «مقادیر جدا شده با ویرگول» است. از این نوع فایل برای جابجایی داده ها و اطلاعات بین نرم افزارهای مختلف استفاده می شود. قالب csv، رایج ترین فرمت وارد کردن و صادر کردن برای صفحات گسترده و پایگاه داده است.

در این نوع فایل داده ها در هر خط به وسیله ی ویرگول از هم جداسازی و محدودسازی می شوند. برای کسب اطلاعات بیشتر در این مورد را مطالعه کنید.

برای نوشتن این برنامه ابتدا یک فایل csv با نامی دلخواه ذخیره می کنیم. سپس مقادیر زیر را در آن ذخیره می کنیم.

ali, 16, 17, 14, 19, 16hamid, 13, 15 , 20 ,  6, 17jafar, 18, 12, 16 , 8 , 6 , 15zahra, 17, 14 , 20,  19, 18 ,16reza, 14, 20 , 5, 8 , 16negar, 19, 18, 16 ,17, 12maryam, 11, 18 , 16 , 9, 16

اکنون مقدمات لازم برای نوشتن برنامه را در اختیار داریم و می توانیم به سراغ کدنویسی برنامه برویم.

نوشتن برنامه خواندن و نوشتن فایل csv در پایتون

قبل از هر چیز لازم است ابتدا کتابخانه هایی که نیاز داریم را با دستور import در ابتدای کد وارد کنیم. برای این برنامه ما به کتابخانه ای برای خواندن و نوشتن فایل های csv نیاز داریم، که می توانیم از کتابخانه ی csv استفاده کنیم.

برای گرفتن معدل نمرات نیز ترجیح می دهیم از متد mean استفاده کنیم، که این متد در چند کتابخانه مختلف از جمله کتابخانه های statistics و math تعریف شده است. از آنجایی که این ها کتابخانه های بزرگ و پر حجمی هستند و وارد کردن کامل آن ها داخل کد، باعث کندی کد خواهد شد، لذا ما فقط متد mean را وارد می کنیم. به این صورت:

import csvfrom statistics import mean…

دستور Open در پایتون

اکنون باید در برنامه، فایل خود را باز کنیم که برای خواندن و نوشتن در فایل از تابع open() استفاده می کنیم. برای آن که کد ما از نحو نگارشی و مدیریت استثناء (Exception handling) بهتری برخوردار شود، از دستور with در کنار تابع open() استفاده می کنیم. ضمن اینکه در این شیوه، فایل پس از اتمام کار به صورت خودکار بسته می شود. روش باز کردن فایل به این صورت است:

import csvfrom statistics import meanwith open(‘grade.csv’, ‘r’) as csvfile:…

چون آدرس دهی دایرکتوری در ویندوز و لینوکس متفاوت است، لذا در قطعه کد بالا، در قسمتی که نام فایل csv را نوشتیم (‘grade.csv’)، باید با توجه به سیستم عامل رایانه ی خود آدرس محلی که فایل csv را ذخیره کرده اید را به صورت کامل اضافه کنید.

همان گونه که می بینید، در تابع open بعد از آدرس فایل، آرگومان دیگری که حرف r است، نوشته شده است. این همان حالتی است که مشخص می کند فایل باید خوانده یا نوشته شود. گزینه های مختلفی برای این منظور وجود دارد ولی پرکاربردترین آنها موارد زیر است:

  • “r” : خواندن (Read) – (مقدار پیش فرض) – فایلی را برای خواندن باز می کند و اگر فایل وجود نداشته باشد، خطایی بر می گرداند.
  • “w”: نوشتن (Write) – فایلی را برای نوشتن باز می کند و اگر فایل وجود نداشته باشد، فایل را ایجاد می کند.
  • “a”: اضافه کردن (َAppend) – فایلی را برای اضافه کردن مقادیر باز می کند و اگر فایل وجود نداشته باشد، آن را ایجاد می کند.
  • “x” : ایجاد کردن (Create) – فایلی مشخص شده را ایجاد می کند و در صورت وجود داشتن فایل، خطایی بر می گرداند.

بعد از باز کردن فایل، باید با کمک کتابخانه ی csv آن را بخوانیم. به این صورت:

…with open(grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    #نام به دلخواه است و هر نام دیگری می توانید تعیین کنید…

اکنون تمامی محتویات فایل ما، در reader وجود دارد که برای مشاهده ی آن ها باید از حلقه ی تکرار for استفاده کنیم. به این صورت:

…with open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    for row in reader:        print( row(…

اگر در حلقه ی تکرار از دستور پرینت استفاده کنیم، تمامی خطوط فایل csv چاپ می شود. اما نیازی به چاپ کردن نداریم و فقط باید معدل نمرات هر شخص را بگیریم. برای این کار ابتدا نام شخص را جدا کرده و سپس نمرات او را به اعشار تبدیل کرده و داخل لیستی اضافه می کنیم. به این صورت:

…reader = csv.reader(csvfile)for row in reader:    name = row[0]    grade_mean = []    for grade in row[1:]:        grade_mean.append(float(grade))..

در پایتون این امکان وجود دارد که چند خط از کد بالا را در یک خط خلاصه کنیم. این قدرت پایتون را نشان می دهد. به این صورت:

…reader = csv.reader(csvfile)for row in reader:    name = row[0]    grade_mean = (float(grade) for grade in row[1:])…

در اینجا نام شخص و لیست نمرات او جدا سازی شد و اکنون فقط کافی است با استفاده از متد mean معدل آن را بگیریم.

برای آن که اطلاعات به دست آورده خود را بعد در فایل ذخیره کنیم، لازم است ابتدا آن ها را در لیست یا دیکشنری ذخیره کنیم. پس بعد از قسمتی که reader را تعریف کردیم یک لیست تعریف می کنیم و در پایان حلقه ی for مقادیر را به لیست اضافه می کنیم. به این صورت:

…with open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    list_grade = []    for row in reader:        name = row[0]        grade_mean = (float(grade) for grade in row[1:])        list_grade.append([row[0], mean(grade_mean)])…

ساخت فایل در پایتون

قسمتی که مربوط به خواندن فایل و گرفتن معدل می شد، تکمیل شد اکنون نوبت به ایجاد فایل جدید و نوشتن نام و معدل دانشجوها در آن می رسد. برای این کار نیز از with open استفاده می کنیم اما حالت آن را  “w” انتخاب می کنیم. به این صورت:

…with open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    list_grade = []    for row in reader:        name = row[0]        grade_mean = (float(grade) for grade in row[1:])        list_grade.append([name, mean(grade_mean)])    with open(‘mean.csv’, ‘w’, newline=”) as outfile:…

نکته 1: تابع open دوم که برای نوشتن استفاده می شود باید داخل تابع open اول نوشته شود.

نکته 2: آرگومان سومی که داخل تابع open نوشته شده است (newline=”) باعث می شود خطوط اضافه داخل فایل نوشته نشود.

فایل دوم ما نیز باز شده و آماده برای نوشتن اطلاعات است. اکنون باید آن را به وسیله ی کتابخانه ی csv فراخوانی و اطلاعات لیست خود را روی آن بنویسیم. برای این منظور از دستور زیر استفاده می کنیم.

…with open(‘mean.csv’, ‘w’, newline=”) as outfile:    writer = csv.writer(outfile)…

در قدم آخر، با یک حلقه ی تکرار for لیستی که اطلاعات را روی آن ذخیره کردیم را پیمایش کرده و خط به خط روی فایل جدید می نویسیم. به این صورت:

…with open(‘mean.csv’, ‘w’, newline=”) as outfile:    writer = csv.writer(outfile)    for item in list_grade:        writer.writerow(item)

اکنون کدنویسی برنامه ی ما به پایان رسید و موفق شدیم اطلاعات یک فایل را خوانده و روی فایلی دیگر، اطلاعاتی جدیدتر بنویسیم. کد کامل و یک جای ما به صورت زیر است:

import csvfrom statistics import meanwith open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    list_grade = []    for row in reader:        name = row[0]        grade_mean = (float(grade) for grade in row[1:])        list_grade.append([name, mean(grade_mean)])    with open(‘mean.csv’, ‘w’, newline=”) as outfile:        writer = csv.writer(outfile)        for item in list_grade:            writer.writerow(item)

روشی برای ساخت فایل در پایتون

در کدی که در بالا نوشتیم، بعضی موارد می تواند بهبود یافته و از حجم کد کاسته شود و هم کد ما بهینه تر شود. ما در ادامه سعی خواهیم کرد که کد خود را بهبود ببخشیم.

در این قسمت، ما تابع open دوم را دقیقا بعد از reader می نویسیم. به این صورت:

import csvfrom statistics import meanwith open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    with open(‘mean.csv’, ‘w’, newline=”) as outfile:        writer = csv.writer(outfile)…

حال عملیاتی که در بالا در open اول نوشتیم را در اینجا در تابع open دوم می نویسیم. و در اینجا لیست list_grade را حذف می کنیم. به این صورت:

…with open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    with open(‘mean.csv’, ‘w’, newline=”) as outfile:        writer = csv.writer(outfile)        for row in reader:            name = row[0]            grade_mean = (float(grade) for grade in row[1:])…

در ادامه بدون هیچ واسطه ای، اطلاعات را مستقیم روی فایل دوم ذخیره می کنیم. به این صورت:

…with open(‘mean.csv’, ‘w’, newline=”) as outfile:    writer = csv.writer(outfile)    for row in reader:        name = row[0]        rade_mean = (float(grade) for grade in row[1:])        writer.writerow([name, mean(grade_mean)])

کد ما کوتاه تر و بهینه تر شد اما هنوز می توانیم متغیر name را نیز حذف کرده و در هنگام نوشتن روی فایل از row[0] استفاده کنیم. به این صورت:

…with open(‘mean.csv’, ‘w’, newline=”) as outfile:    writer = csv.writer(outfile)    for row in reader:        grade_mean = (float(grade) for grade in row[1:])        writer.writerow([row[0], mean(grade_mean)])

ما با اندکی ظرافت و خلاقیت، کد خود را بهینه و خلاصه تر کردیم. همیشه کدهای بهینه شده از سرعت و خوانایی بالاتری برخوردار است. کد کامل شده ی ما به صورت زیر است:

import csvfrom statistics import meanwith open(‘grade.csv’, ‘r’) as csvfile:    reader = csv.reader(csvfile)    with open(‘mean.csv’, ‘w’, newline=”) as outfile:        writer = csv.writer(outfile)        for row in reader:            grade_mean = (float(grade) for grade in row[1:])            writer.writerow([row[0], mean(grade_mean)])

شما می توانید هر دو کد را با هم بررسی کرده و تفاوت ها و شباهت های آن ها را مشاهده کنید و به طور قطع متوجه خواهید شد که کد دوم بسیار خواناتر از کد اول است، هر چند که کار هر دو کد یکی است.

خواندن و نوشتن فارسی در فایل پایتون

یکی از مشکلاتی که ممکن است هنگام کار با فایل ها در پایتون پیش آید و باعث ایجاد خطا گردد، وجود داشتن حروف و کاراکتر فارسی در فایل ها است. اگر به چنین مشکلی برخورد کردید، فقط کافی ست آرگومان “encoding=utf-8” را در داخل تابع open اضافه کنید. با این کار، پایتون با یونیکد UTF8 ، کاراکترهای فارسی را شناخته و از بروز خطای احتمالی جلوگیری می کند. به این صورت:

…with open(‘grade.csv’, ‘r’, encoding=’utf-8′) as csvfile:     reader = csv.reader(csvfile)    with open(‘mean.csv’, ‘w’, encoding=’utf-8′, newline=”) as outfile:        writer = csv.writer(outfile)…

کار با فایل ها در پایتون برای خواندن فایل csv در پایتون چگونه انجام می شود؟

فایل ها برای ذخیره اطلاعات در برنامه نویسی بسیار کاربردی است. برای آن که بتوانیم اطلاعات خود را در برنامه های دیگر و نیز در دفعات دیگر استفاده کنیم، ملزم به ذخیره در فایل هستیم. ما در مقاله ی کار با فایل ها در پایتون، برنامه ای نوشتیم که از یک فایل نمرات یک دانشجو را خوانده و پس از گرفتن معدل آن ها، در فایلی ذخیره کردیم. خواندن و نوشتن روی فایل در پایتون کار جذاب و با اهمیتی است که هر برنامه نویس پایتون، باید آن را بیاموزد.

در کار با فایل در پایتون برنامه های کاربردی تر و بهتری نیز می توان نوشت. اگر از علاقه مندان به برنامه نویسی پایتون هستید، می توانید به عنوان تمرین، برنامه خواندن و نوشتن فایل csv در پایتون را به روش هایی دیگر بنویسید.

اگر قصد دارید در مدت زمان کوتاهی برنامه نویسی را فرابگیرید، در این مسیر پر فراز و نشیب همراه شما خواهند بود.

اگر به یادگیری بیشتر در زمینه ی برنامه نویسی پایتون علاقه داری، یادگیری زبان پایتون بسیار ساده است. و با شرکت در دوره ی توسعه وب در آینده می تونی اپلیکیشن موبایل و دسکتاپ بسازی و وارد حوزه ی هوش مصنوعی هم شوید.

منبع:  آموزش خواندن و ساخت فایل در پایتون

دکمه بازگشت به بالا