תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

מדריך CSV בפייתון

מחבר:
בתאריך:

CSV - הוא פורמט מקובל לאחסון מידע טבלאי בקבצים. בדומה לאקסל.

מדריך csv python

בניגוד לאקסל, מסמך CSV הוא קובץ טקסט פשוט שניתן לצפות בו באמצעות עורך טקסט פשוט (דוגמת Notepd על גבי מערכת הפעלה חלונות).

כדאי להמיר קבצי אקסל ל-CSV כי היתרון הגדול של CSV הוא שניתן לעבוד איתו ממש בקלות בכל שפת מחשב (קראו כיצד להסב Excel ל-CSV).

כל שורה של קובץ CSV מהווה שורה בטבלה, ופסיקים מפרידים בין התאים. מכאן השם, Comma Separated Values או בקיצור CSV.

כך נראה קובץ CSV:

id,model,date,owner
1,BMW,6-8-2019,משה
2,Tesla,11-7-2019,אלון
3,Mercedes,14-1-2020,צבי
4,Jeep,13-2-2020,חני
5,Jaguar,27-11-2019,נועם
6,BMW,11-11-2018,תהילה
  • המידע מסודר בשורות
  • בכל שורה מספר תאים שפסיקים מפרידים ביניהם
  • השורה הראשונה מכילה את שמות העמודות
  • יתר השורות מכילות את המידע

קובץ ה-CSV הזה ישמש אותנו במדריך. אתה מוזמן להוריד אותו מכאן: csv_tutorial.zip

בעיקרון, ניתן להשתמש בפונקציות מחרוזת של פייתון כדי לטפל בקבצי CSV אבל במדריך הזה נשתמש במודולים המובנים של פייתון שמאפשרים לנו לעבוד עם CSV בקלות ובבטחון.

כל המודולים לטיפול ב-CSV במדריך הם מודולים מובנים של פייתון. אין צורך להתקין אותם.

 

כיצד לקרוא קבצי CSV באמצעות אובייקט reader

אובייקט reader קורא קבצים של CSV, ויוצר מהם רשימות.

נשים את קובץ ה-CSV באותה התיקייה עם הסקריפט main.py, ובתוך הסקריפט נוסיף את הקוד שקורא את הקובץ:

main.py

import csv

with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    print(myReader)
  • את הקובץ פתחנו לקריאה באמצעות open().
  • הפונקציה csv.reader() קוראת את תוכנו של הקובץ לתוך משתנה פייתוני.

התוצאה:

<_csv.reader object at 0x7fca6ca32208>

התוצאה היא iterable שהוא אובייקט שמכיל סידרה של ערכים. כדי לצפות בערכים צריך להפעיל לולאת for או להשתמש בפונקציה list().

נוסיף את הפונקציה list() כדי לצפות במידע:

main.py

import csv

myList = []
with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    myList = list(myReader)
    
print(myList)
  • המשתנה myList מכיל את הרשימה.
  • הפונקציה list() קוראת את האובייקט שמחזיר ה-reader לתוך לולאה.

והתוצאה היא רשימה המורכבת מרשימות:

[['id', 'model', 'date', 'owner'], ['1', 'BMW', '6-8-2019', 'משה'], ['2', 'Tesla', '11-7-2019', 'אלון'], ['3', 'Mercedes', '14-1-2020', 'צבי'], ['4', 'Jeep', '13-2-2020', 'חני'], ['5', 'Jaguar', '27-11-2019', 'נועם'], ['6', 'BMW', '11-11-2018', 'תהילה']]
  • כיוון ש-csv הוא מודול מובנה של פייתון מייבאים אותו ללא צורך בהתקנה.
  • את קובץ ה-csv פתחנו לקריאה באמצעות context manager כמו שעשינו במדריך עבודה עם קבצים בפייתון.
  • את אובייקט הקובץ ש-open מחזיר מעבירים לפונקציה csv.reader() המחזירה אובייקט reader.
  • הפעלנו את הפונקציה list() על אובייקט ה-reader כדי לקבל רשימה של רשימות אותה אחסנו בתוך המשתנה myList.

אחרי שהצלחנו לחלץ את המידע מקובץ ה-CSV לתוך משתנה רשימה פייתוני אנחנו יכולים לגשת למידע כמקובל כשעובדים עם רשימות של פייתון.

נשלוף את כל השורה השלישית:

print(myList[2])
['2', 'Tesla', '11-7-2019', 'אלון']

נשלוף את הערך השני מתוך השורה השלישית:

print(myList[2][1])
Tesla

ניתן לעבור על המידע שחילצנו לתוך ה-reader באמצעות לולאת for:

main.py

import csv
with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    
    for myItem in myReader:
        print(myItem)

התוצאה:

['id', 'model', 'date', 'owner']
['1', 'BMW', '6-8-2019', 'משה']
['2', 'Tesla', '11-7-2019', 'אלון']
['3', 'Mercedes', '14-1-2020', 'צבי']
['4', 'Jeep', '13-2-2020', 'חני']
['5', 'Jaguar', '27-11-2019', 'נועם']
['6', 'BMW', '11-11-2018', 'תהילה']
  • כשאנחנו עוברים עם לולאה ישירות על האובייקט שמחזיר ה-reader נוכל להשתמש במידע פעם אחת בלבד. לכן אני מעדיף להפוך את המידע לרשימה באמצעות הפונקציה list(), ולהציב את הרשימה לתוך משתנה שבו אני יכול להשתמש כמה פעמים שצריך:

main.py

import csv

myList = []

with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    myList = list(myReader)

for myItem in myList:
    print(myItem)
  • הפונקציה list() הופכת את המידע מאובייקט ה- reader לרשימה שאותה אנחנו מציבים לתוך המשתנה myList.
  • נעבור על הרשימה באמצעות לולאת for.

התוצאה:

['id', 'model', 'date', 'owner']
['1', 'BMW', '6-8-2019', 'משה']
['2', 'Tesla', '11-7-2019', 'אלון']
['3', 'Mercedes', '14-1-2020', 'צבי']
['4', 'Jeep', '13-2-2020', 'חני']
['5', 'Jaguar', '27-11-2019', 'נועם']
['6', 'BMW', '11-11-2018', 'תהילה']

 

כיצד לסנן את התוצאות שמחזיר אובייקט reader

ניתן לסנן את התוצאות שמגיעות ממסמך CSV בכמה דרכים.

אחת הדרישות הנפוצות כשעובדים עם אובייקט reader היא לסנן את השורה הראשונה שמכילה את שמות העמודות. נשתמש בפונקציה next() ישירות על ה- reader כדי לדלג על השורה הראשונה:

import csv

myList = []

with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    next(myReader)
    myList = list(myReader)

for myItem in myList:
    print(myItem)

התוצאה אינה כוללת את השורה הראשונה במסמך:

['1', 'BMW', '6-8-2019', 'משה']
['2', 'Tesla', '11-7-2019', 'אלון']
['3', 'Mercedes', '14-1-2020', 'צבי']
['4', 'Jeep', '13-2-2020', 'חני']
['5', 'Jaguar', '27-11-2019', 'נועם']
['6', 'BMW', '11-11-2018', 'תהילה']

אפשר גם לסנן לפי המידע הכלול ברשימה.

לדוגמה, רשימת המודלים ששמם מתחיל באות "J":

for myItem in myList:
    if myItem[1].startswith("J"):
        print(myItem)
['4', 'Jeep', '13-2-2020', 'חני']
['5', 'Jaguar', '27-11-2019', 'נועם']

בדוגמה, השתמשנו בפונקצית מחרוזת. אפשר גם להשתמש בביטויים רגולריים.

מכיוון שקובץ CSV הוא קובץ טקסט כל המידע הכלול בו הוא בהכרח מחרוזת. לכן, אם רוצים לעבוד עם תאריכים צריך להפוך אותם לאובייקטים (כמוסבר במדריך על עבודה עם תאריכים בפייתון).

 

כיצד לכתוב קבצי CSV באמצעות אובייקט writer

נשתמש בפונקציה csv.writer() כדי לכתוב לקובץ.

בסעיף קודם, קבלנו רשימה של רשימות שקראנו לה myList. נעבור על פרטי הרשימה בתוך לולאה ונכתוב כל שורה בנפרד לתוך קובץ CSV חדש ששמו models_new.csv:

main.py

import csv
myList = []
with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
    myList = list(myReader)

with open('models_new.csv', 'w') as newFile:
    myWriter = csv.writer(newFile)
    for myItem in myList:
        myWriter.writerow(myItem)

התוצאה היא קובץ new_model.csv שמכיל עותק של קובץ ה-CSV המקורי.

  • פתחנו את הקובץ models_new.csv לכתיבה באמצעות open().
  • הפונקציה csv.writer() מקבלת את אובייקט הקובץ.
  • את הכתיבה עצמה מבצעת הפונקציה writerow() של אובייקט ה-writer בתוך לולאה.

 

מפרידי תאים ושורות שאינם סטנדרטיים

עד כה ראינו קבצי CSV שבהם הפריטים בכל שורה מופרדים בפסיקים אבל יש גם מקרים אחרים. דוגמת השימוש בטאב tab או בנקודה פסיק (;) לשם הפרדה.

על מנת לייצר קובץ CSV שבו התאים מופרדים באמצעות tab נעביר לפונקציה csv.writer() את הפרמטר delimiter:

myWriter = csv.writer(newFile, delimiter="\t")
  • התו \t מסמן טאב.

השיטה עובדת גם כשקוראים קבצים. לדוגמה, קריאת קובץ בו ההפרדה מתבצעת באמצעות נקודה פסיק (;):

myReader = csv.reader(theFile, delimiter=";")

באופן רגיל, כל שורת מידע פותחת שורה חדשה בקובץ. לעיתים, נתקל בקבצים שבהם ההפרדה אינה סטנדרטית. לדוגמה, רווח כפול. הפרמטר lineterminator מאפשר לנו לציין את מפריד השורה בקובץ:

myReader = csv.reader(theFile, delimiter=";", lineterminator="\n\n")
  • התו \n מסמן שורה חדשה. ורצף התווים \n\n מציין רווח כפול.

ננסה את מה שכתבנו:

main.py

import csv
myList = []
with open('models.csv', 'r') as myFile:
    myReader = csv.reader(myFile)
	myList = list(myReader)

with open('models_new.tsv', 'w') as myFile:
    myWriter = csv.writer(myFile, delimiter="\t", lineterminator="\n\n")
    for myItem in myList:
        myWriter.writerow(myItem)

התוצאה היא קובץ tsv (ראשי תיבות של Tab Separated Values):

models_new.tsv

id	model	date	owner

1	BMW	6-8-2019	משה

2	Tesla	11-7-2019	אלון

3	Mercedes	14-1-2020	צבי

4	Jeep	13-2-2020	חני

5	Jaguar	27-11-2019	נועם

6	BMW	11-11-2018	תהילה

 

עבודה עם מילונים במקום עם רשימות

בדרך כלל, השורה הראשונה של קבצי ה-CSV מכילה את שמות העמודות. לדוגמה, הקובץ שאיתו אנחנו עובדים במדריך:

models.csv

id,model,date,owner
1,BMW,6-8-2019,משה
2,Tesla,11-7-2019,אלון
3,Mercedes,14-1-2020,צבי
4,Jeep,13-2-2020,חני
5,Jaguar,27-11-2019,נועם
6,BMW,11-11-2018,תהילה
  • השורה הראשונה מכילה את שמות העמודות
  • יתר השורות מכילות את המידע

האובייקטים DictReader ו-DictWriter קוראים את המידע מקובץ ה-CSV לתוך מילון, ומאפשרים לנו לגשת לפריטי המידע עם המפתחות שהם שמות העמודות.

main.py

import csv

myList = []
with open('models.csv', 'r') as myFile:
    myDictReader = csv.DictReader(myFile)
    myList = list(myDictReader)

for myItem in myList:
    print(myItem)

התוצאה:

OrderedDict([('id', '1'), ('model', 'BMW'), ('date', '6-8-2019'), ('owner', 'משה')])
OrderedDict([('id', '2'), ('model', 'Tesla'), ('date', '11-7-2019'), ('owner', 'אלון')])
OrderedDict([('id', '3'), ('model', 'Mercedes'), ('date', '14-1-2020'), ('owner', 'צבי')])
OrderedDict([('id', '4'), ('model', 'Jeep'), ('date', '13-2-2020'), ('owner', 'חני')])
OrderedDict([('id', '5'), ('model', 'Jaguar'), ('date', '27-11-2019'), ('owner', 'נועם')])
OrderedDict([('id', '6'), ('model', 'BMW'), ('date', '11-11-2018'), ('owner', 'תהילה')])
  • הפונקציה csv.DictReader() הופכת את קובץ ה- CSV לאובייקטים מסוג OrderedDict בהם נשתמש כמילון רגיל.

כמו במילונים ניגש לפריטי המידע באמצעות מפתחות במקום באמצעות מספרי האינדקס:

main.py

import csv
myList = []
with open('models.csv', 'r') as myFile:
    myDictReader = csv.DictReader(myFile)
    myList = list(myDictReader)

for myItem in myList:
    print(myItem['model'], myItem['owner'])

התוצאה:

BMW משה
Tesla אלון
Mercedes צבי
Jeep חני
Jaguar נועם
BMW תהילה

בקובץ ה-CSV במדריך שמות העמודות מופיעים בשורה הראשונה אבל לא כל המסמכים הם כל כך מסודרים. במצב שבו המסמך לא מכיל את שמות העמודות נספק את השמות בתור הפרמטר השני שנעביר לפונקציה csv.DictReader():

myDictReader = csv.DictReader(myFile, ['id','model','date','owner'])

ניתן להשתמש במילונים כדי לקרוא קובץ CSV וגם כדי לכתוב.

נשתמש בפונקציה csv.DictWriter() כדי לכתוב לקובץ:

main.py

import csv

myList = []
with open('models.csv', 'r') as myFile:
    myDictReader = csv.DictReader(myFile)
    myList = list(myDictReader)

with open('models_new.csv', 'w') as newFile:
    myDictWriter = csv.DictWriter(newFile, ['id','model','date','owner'])
    myDictWriter.writeheader()
    for myItem in myList:
        myDictWriter.writerow(myItem)
  • הפונקציה csv.DictWriter() מקבלת את שם הקובץ לתוכו רוצים לכתוב ואת רשימת שמות העמודות.
  • הפקודה myWriter.writeheader() כותבת את השורה הראשונה עם שמות העמודות. במידה ולא רוצים שהמסמך יכלול את שמות העמודות אפשר לוותר עליה.

 

מיני-פרויקט: הפיכת קובץ CSV ל-HTML

המטרה של המיני-פרויקט במדריך היא להציג לסנן את בעלי ה- BMW מתוך ה-CSV ולהציג אותם ברשימת HTML.

בשלב ראשון, נאחסן את המידע שמקורו ב-CSV בתוך משתנה פייתון.

import csv
myList = []
with open('models.csv', 'r') as myFile:
    myDictReader = csv.DictReader(myFile)
    myList = list(myDictReader)

בשלב שני, נבנה את ה-HTML בתוך לולאה:


import csv
myList = []
with open('models.csv', 'r') as myFile:
    myDictReader = csv.DictReader(myFile)
    myList = list(myDictReader)
 
build = "<ul>\n"
for myItem in myList:
    if myItem['model'] == 'BMW':
        build += f"\t<li>{myItem['owner']} הוא הבעלים הגאה של {myItem['model']}</li>\n"
build += ""

print(build)
  • המשתנה build מכיל את מחרוזת ה-HTML.
  • את ה-HTML אנחנו בונים בתוך לולאה.
  • לבניית כל שורה נשתמש ב-F-string המאפשר לשלב משתנים בתוך המחרוזת (כפי שהסברתי במדריך על מחרוזות בפייתון).

התוצאה:

<ul>
	<li>משה הוא הבעלים הגאה של BMW</li>
	<li>תהילה הוא הבעלים הגאה של BMW</li>
</ul>

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.

למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

איך אומרים בעברית אינטרנט?

 

תמונת המגיב

אלי בתאריך: 02.11.2020

מדריכים נפלאים !!!
אבל לא ברור לי איך כותבים לעמודה ספציפית בשורה ספציפית :
csv קורה את הקובץ כ list of lists כך שבקריאה אני יכול לייבא את הקובץ לרשימה ואחר כך לסמן איזה איבר ברשימה אני רוצה לראות
אבל לא ברור לי איך כ ו ת ב ים לקובץ , אם אני אוציא מאובייקט בwrither את כל הרשימות - אוכל לשנות את האיבר בתוך בתוכנה - איך אני מפנה את את הwrither לתא ספציפי בשורה ספציפית ?

תמונת המגיב

דד בתאריך: 16.12.2020

וואוו מדריך מעולה . תודה

תמונת המגיב

אילה בתאריך: 04.07.2022

מדריך מושלם וברור אש!!!!