مقدمه
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 در پایتون را به روشهایی دیگر بنویسید.
اگر قصد دارید در مدت زمان کوتاهی برنامه نویسی را فرابگیرید، در این مسیر پر فراز و نشیب همراه شما خواهند بود.
اگر به یادگیری بیشتر در زمینهی برنامه نویسی پایتون علاقه داری، یادگیری زبان پایتون بسیار ساده است. و با شرکت در دورهی توسعه وب در آینده میتونی اپلیکیشن موبایل و دسکتاپ بسازی و وارد حوزهی هوش مصنوعی هم شوید.
منبع: آموزش خواندن و ساخت فایل در پایتون