الجداول كنص
يخزّن ملف CSV (قيم مفصولة بفواصل) جدولًا كنص: صف لكل سطر وخلايا مفصولة بفواصل، وغالبًا مع صف رأس يسمّي الأعمدة. تأتي سجلات الأسعار ودفاتر الصفقات وتصديرات أي أداة تقريبًا بهذا الشكل. يبدو تحليله سهلًا بـline.split(",")، لكن قد تحتوي الخلية نفسها على فاصلة، فتُحاط بعلامات اقتباس: AAPL,"Q3, adjusted". والتقسيم اليدوي يفشل هنا، فاستخدم الوحدة القياسية csv وافتح الملف بـnewline="" لتُعالَج فواصل الأسطر داخل الخلايا معالجة صحيحة.
import csv
# Write a small table with csv.writer
with open("prices.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["date", "symbol", "close", "note"])
writer.writerow(["2025-01-02", "AAPL", 184.25, "Q3, adjusted"])
writer.writerow(["2025-01-03", "AAPL", 185.5, ""])
# The comma inside the note is quoted for us
with open("prices.csv", encoding="utf-8") as file:
print(file.read().splitlines()[1]) # 2025-01-02,AAPL,184.25,"Q3, adjusted"قراءة الصفوف
تُنتج csv.reader(file) كل صف كـقائمة نصوص. أما csv.DictReader(file) فتقرأ الرأس أولًا ثم تنتج كل صف كـقاموس مفاتيحه أسماء الأعمدة، وهو أسهل قراءة ولا يتأثر بتغيير ترتيب الأعمدة. وفي الحالتين كل خلية نص: حوّلها بـfloat(...) أو int(...) قبل الحساب. مرّر delimiter=";" (أو "\t") للملفات التي تستخدم فاصلًا آخر.
import csv
# DictReader gives each row as a dict; cells are strings
closes = []
with open("prices.csv", newline="", encoding="utf-8") as file:
for row in csv.DictReader(file):
closes.append(float(row["close"]))
print(closes) # [184.25, 185.5]
# csv.reader gives plain lists, header included
with open("prices.csv", newline="", encoding="utf-8") as file:
rows = list(csv.reader(file))
print(rows[0]) # ['date', 'symbol', 'close', 'note']
print(rows[1]) # ['2025-01-02', 'AAPL', '184.25', 'Q3, adjusted']كتابة الصفوف
تكتب csv.writer(file).writerow(values) صفًا واحدًا وتضع علامات الاقتباس عند الحاجة، وتحوّل الأرقام إلى نص عنك. وتكتب csv.DictWriter(file, fieldnames=[...]) قواميس، وتكتب writeheader() أسماء الأعمدة أولًا. افتح الملف بـ"w" وnewline=""؛ فبدون newline="" قد تظهر في ويندوز أسطر فارغة بين الصفوف.
import csv
# DictWriter: header first, then one dict per row
trades = [{"symbol": "AAPL", "quantity": 200}, {"symbol": "MSFT", "quantity": 50}]
with open("trades.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=["symbol", "quantity"])
writer.writeheader()
writer.writerows(trades)
with open("trades.csv", encoding="utf-8") as file:
print(file.read().splitlines()) # ['symbol,quantity', 'AAPL,200', 'MSFT,50']import csv
# Cells are text until you convert them
with open("prices.csv", newline="", encoding="utf-8") as file:
row = next(csv.DictReader(file))
print(repr(row["close"]), row["close"] * 2) # '184.25' 184.25184.25
print(float(row["close"]) * 2) # 368.5
# Another separator: semicolons
with open("euro.csv", "w", newline="", encoding="utf-8") as file:
csv.writer(file, delimiter=";").writerow(["AAPL", "184,25"])
with open("euro.csv", newline="", encoding="utf-8") as file:
print(next(csv.reader(file, delimiter=";"))) # ['AAPL', '184,25']184.25 و200 وAAPL مجرد أحرف حتى تحوّلها. ونسيان ذلك يعطي "184.25" * 200 (النص مكررًا 200 مرة) بدل خطأ. حوّل كل عمود مرة واحدة عند قراءته، وتحقق من أسماء الرأس بدل افتراض المواضع.- افتح بـ
newline=""؛ ولا تقسّم أسطر CSV أو تدمجها يدويًا. - تقرأ
csv.DictReaderالصفوف كقواميس؛ وكل خلية نص. csv.writer/csv.DictWriterتكتبان الصفوف وتضعان علامات الاقتباس عنك.
التالي: بيانات JSON، للسجلات المتداخلة التي لا تناسب جدولًا مسطحًا.
المختبر: ما الذي يُقيَّم
- جمّع أسعار الإغلاق بحسب الرمز باستخدام
read_closes25 نقطة - احفظ الصفقات كملف CSV باستخدام
write_trades25 نقطة - اجمع القيمة المتداولة لكل رمز باستخدام
total_by_symbol25 نقطة - انسخ صفوف رمز واحد إلى ملف جديد باستخدام
filter_rows25 نقطة