في المجالات التي تعتمد على البيانات، مثل تحليل البيانات وتعلم الآلة وتطوير الويب، غالبًا ما تحتاج إلى تحويل البيانات من صيغة إلى أخرى لتلبية احتياجات محددة. ومن المتطلبات الشائعة تحويل قائمة بايثون إلى سلسلة CSV، مما يتيح مشاركة البيانات وتخزينها بتنسيق مقبول عالميًا وسهل الحمل.
في هذه المقالة، سنتعمق في هذه العملية تحديدًا. في نهايتها، ستفهم كيفية تحويل قوائم بايثون إلى سلاسل نصية بتنسيق CSV باستخدام وحدة csv. سنستكشف القوائم البسيطة، بالإضافة إلى قوائم القواميس الأكثر تعقيدًا، ونناقش خيارات ومعايير مختلفة تساعدك في التعامل مع أصعب مهام التحويل.
فهم قوائم بايثون وملفات CSV
قبل أن نتعمق في عملية التحويل، من الضروري أن نفهم اللاعبين الرئيسيين المعنيين: قوائم بايثون وملفات CSV.
قوائم بايثون
القائمة في بايثون هي نوع بيانات مدمج يمكنه تخزين عناصر غير متجانسة. بمعنى آخر، يمكنها تخزين أنواع مختلفة من البيانات (مثل الأعداد الصحيحة، والسلاسل النصية، وحتى القوائم الأخرى) بتسلسل منظم.
لإنشاء قائمة في بايثون، قم بإحاطة العناصر الخاصة بك بأقواس مربعة []
، وفصل كل عنصر بفاصلة:
python_list = ["dog", 33, ["cat", "billy"]]
يمكنك الوصول إلى العناصر وتعديلها وإزالتها في قائمة استنادًا إلى موضعها (الفهرس)، وتدعم القوائم عمليات مختلفة مثل التقطيع والتسلسل والتكرار.
ملفات CSV
ملفات CSV (القيم المفصولة بفواصل) هي ملفات نصية عادية تحتوي على بيانات جدولية. يمثل كل سطر في الملف صفًا من الجدول، وكل قيمة (خلية) فيه مفصولة بفاصلة، ومن هنا جاء الاسم.
name,age,city
John,27,New York
Jane,22,Los Angeles
في المثال السابق، يُشار عادةً إلى السطر الأول بالعنوان، ويمثل أسماء الأعمدة. الأسطر التالية هي صفوف البيانات.
تُستخدم ملفات CSV عالميًا لأغراض متعددة. فهي سهلة الفهم والإنشاء، ويمكن قراءتها بواسطة العديد من أنواع البرامج، بما في ذلك برامج جداول البيانات مثل Microsoft Excel وGoogle Sheets، وبالطبع لغات البرمجة مثل Python.
نحن الآن جاهزون للانطلاق في عملية التحويل الفعلية باستخدام مكتبة csv الخاصة بـ Python.
مكتبة csv
وحدة csv المدمجة في بايثون هي مجموعة أدوات فعّالة تُسهّل قراءة وكتابة ملفات CSV. كما تُتيح إمكانية تسلسل البيانات وإلغاء تسلسلها، والتحويل بين تنسيق بيانات CSV وهياكل بيانات بايثون المُخزّنة في الذاكرة.
قبل أن نتمكن من استخدام مكتبة csv، علينا استيرادها إلى برنامج بايثون النصي. الأمر بسيط للغاية، ما عليك سوى استخدام الكلمة الفتاحة import
:
import csv
بفضل هذا السطر في بداية البرنامج النصي الخاص بنا، أصبح بإمكاننا الآن الوصول إلى دوال مكتبة csv.
توفر مكتبة csv عدة توابه لقراءة وكتابة بيانات CSV، ولكن لغرض هذه المقالة، سنحتاج إلى عدد قليل منها فقط:
csv.writer()
– يعيد كائن كاتب مسؤول عن تحويل بيانات المستخدم إلى سلاسل محددة على كائن يشبه الملف المحدد.csv.DictWriter()
– تُرجع كائن كاتب يُعيّن القواميس إلى صفوف الإخراج. معلمة أسماء الحقول هي سلسلة مفاتيح تُحدد ترتيب كتابة قيم القاموس في ملف CSV.
الآن، يمكننا الانتقال إلى رؤية كيفية استخدامه لتحويل قائمة Python إلى سلسلة CSV.
تحويل قائمة بايثون إلى سلسلة CSV
تحويل قائمة بايثون إلى سلسلة نصية CSV سهلٌ جدًا باستخدام وحدة csv. لنُقسّم هذه العملية إلى خطوات.
كما ناقشنا سابقًا، قبل أن نتمكن من استخدام وحدة csv، نحتاج إلى استيرادها:
import csv
بعد ذلك، نحتاج إلى إنشاء قائمة:
python_list = ["dog", 33, ["cat", "billy"]]
بعد إنشاء القائمة واستيراد وحدة csv، يُمكننا تحويلها إلى سلسلة نصية CSV. أولًا، سننشئ كائن StringIO، وهو كائن شبيه بالملفات في الذاكرة:
import io
output = io.StringIO()
نقوم بعد ذلك بإنشاء كائن csv.writer باستخدام كائن StringIO هذا:
writer = csv.writer(output)
يسمح لنا التابع writerow()
الخاص بكائن csv.writer بكتابة القائمة إلى كائن StringIO كصف في ملف CSV:
writer.writerow(python_list)
أخيرًا، نسترد سلسلة CSV عن طريق استدعاء getvalue على كائن StringIO:
csv_string = output.getvalue()
باختصار، يجب أن يبدو الكود الخاص بنا على هذا النحو:
import csv
import io
python_list = ["dog", 33, ["cat", "billy"]]
output = io.StringIO()
writer = csv.writer(output)
writer.writerow(python_list)
csv_string = output.getvalue()
print(csv_string)
يجب أن يمنحنا هذا تمثيلًا بتنسيق CSV لـ python_list:
dog,33,"['cat', 'billy']"
العمل مع قوائم القواميس
بينما تُعدّ القوائم ممتازةً للتعامل مع مجموعات العناصر المُرتّبة، إلا أن هناك حالاتٍ نحتاج فيها إلى بنيةٍ أكثر تعقيدًا للتعامل مع بياناتنا، مثل قائمة القواميس. تكتسب هذه البنية أهميةً خاصة عند التعامل مع بياناتٍ يُمكن تمثيلها بشكلٍ أفضل في شكل جدول.
قوائم القواميس في بايثون
في بايثون، القاموس هو مجموعة غير مرتبة من العناصر. يُخزَّن كل عنصر كزوج مفتاح-قيمة. قوائم القواميس هي هياكل بيانات شائعة، حيث يكون كل عنصر فيها قاموسًا.
users = [
{"name": "John", "age": 27, "city": "New York"},
{"name": "Jane", "age": 22, "city": "Los Angeles"},
{"name": "Dave", "age": 31, "city": "Chicago"}
]
في هذه القائمة، يمثل كل قاموس مستخدمًا، مع تخزين اسمه وعمره ومدينته كأزواج مفتاح-قيمة.
كتابة قائمة قواميس إلى سلسلة CSV
لكتابة قائمة قواميس إلى سلسلة نصية بتنسيق CSV، سنستخدم الدالة csv.DictWriter()
التي ذكرناها بإيجاز سابقًا. نحتاج أولًا إلى تعريف أسماء الحقول كقائمة من السلاسل النصية، وهي مفاتيح قواميسنا:
fieldnames = ["name", "age", "city"]
نقوم بعد ذلك بإنشاء كائن DictWriter، ونمرر إليه كائن StringIO وfieldnames:
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=fieldnames)
نحن نستخدم التابع writeheader لكتابة fieldnames كرأس لسلسلة CSV:
writer.writeheader()
أخيرًا، نقوم بالمرور عبر قائمة القواميس، ونكتب كل قاموس كصف في سلسلة CSV باستخدام التابع writerow:
for user in users:
writer.writerow(user)
في النهاية، يجب أن يبدو الكود الخاص بنا بهذا الشكل:
import csv
import io
users = [
{"name": "John", "age": 27, "city": "New York"},
{"name": "Jane", "age": 22, "city": "Los Angeles"},
{"name": "Dave", "age": 31, "city": "Chicago"}
]
output = io.StringIO()
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(output, fieldnames=fieldnames)
writer.writeheader()
for user in users:
writer.writerow(user)
csv_string = output.getvalue()
print(csv_string)
عند تشغيل هذا البرنامج النصي، سوف ترى الناتج التالي:
name,age,city
John,27,New York
Jane,22,Los Angeles
Dave,31,Chicago
يُظهر هذا أن قائمة قواميسنا قد حُوِّلت بنجاح إلى سلسلة CSV. أصبح كل قاموس في القائمة صفًا في سلسلة CSV، حيث تُمثِّل المفاتيح رؤوس الأعمدة والقيم بيانات الصفوف.
كيفية اختيار الفواصل المختلفة
افتراضيًا، تستخدم وحدة csv فاصلة كفاصل بين القيم. مع ذلك، يمكنك استخدام فاصل مختلف عند الحاجة. يمكنك تحديد الفاصل عند إنشاء كائن csv.writer أو csv.DictWriter. لنفترض أننا نريد استخدام فاصلة منقوطة كفاصل:
import csv
import io
fruits = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']
output = io.StringIO()
# Define the delimiter here:
writer = csv.writer(output, delimiter=';')
writer.writerow(fruits)
csv_string = output.getvalue()
print(csv_string)
يجب أن يمنحنا هذا سلسلة CSV مع استخدام الفواصل المنقوطة كفاصلات:
Apple;Banana;Cherry;Date;Elderberry
إدارة الاقتباسات
ربما لاحظتَ ذلك بالفعل، لكن وحدة csv تُرجع سلسلة CSV بدون علامات اقتباس. من ناحية أخرى، كل عنصر من القائمة الأصلية يحتوي على حرف خاص، مثل فاصل أو سطر جديد أو علامة اقتباس، سيكون في الواقع محاطًا بعلامات اقتباس.
import csv
import io
fruits = ['Apple', 'Ban,ana', 'Cherry', 'Dat\ne', 'Elderberry']
output = io.StringIO()
# Managing quoting here:
writer = csv.writer(output)
writer.writerow(fruits)
csv_string = output.getvalue()
print(csv_string)
تمشيا مع ما قلناه من قبل، سيتم اقتباس عناصر قائمة الفاكهة التي تحتوي على أحرف خاصة فقط:
Apple,"Ban,ana",Cherry,"Dat
e",Elderberry
يمكنك التحكم في هذا السلوك باستخدام معلمتي quotechar وquoting. تحدد معلمة quotechar الحرف المستخدم للاقتباس. الافتراضي هو علامة اقتباس مزدوجة (“)، ويمكننا تغييرها إلى علامة اقتباس مفردة (‘) مثلاً بتحديد معلمة quotechar في دالة csv.writer()
:
writer = csv.writer(output, quotechar="'")
سيتم الآن اقتباس نفس العناصر كما في السابق في سلسلة الإخراج، ولكن باستخدام علامات الاقتباس المفردة:
Apple,'Ban,ana',Cherry,'Dat
e',Elderberry
هناك معلمة أخرى تتحكم في الاقتباس في وحدة csv، وهي معلمة quoting. تتحكم هذه المعلمة في وقت إنشاء الاقتباسات بواسطة دالة csv.writer()
. يمكن أن تأخذ أيًا من ثوابت وحدة csv التالية بناءً على وقت اقتباس عناصر القائمة:
csv.QUOTE_MINIMAL
– عرض عناصر الاقتباس فقط عند الضرورة (افتراضي)csv.QUOTE_ALL
– اقتباس جميع العناصرcsv.QUOTE_NONNUMERIC
– اقتباس كافة العناصر غير الرقميةcsv.QUOTE_NONE
– لا تقتبس أي شيء
لنفترض أننا نريد اقتباس جميع عناصر قائمة الفواكه. سنحتاج إلى ضبط مُعامل الاقتباس لدالة csv.writer()
إلى csv.QUOTE_ALL
:
writer = csv.writer(output, quoting=csv.QUOTE_ALL)
وهذا سيعطينا:
"Apple","Ban,ana","Cherry","Dat
e","Elderberry"
الأخطاء الشائعة وإصلاحها
على الرغم من بساطته النسبية، قد يُشكّل تحويل قوائم بايثون إلى سلاسل CSV بعض التحديات. دعونا نستعرض بعض المشاكل الشائعة وحلولها.
اقتباسات غير متوازنة في بيانات CSV
إذا كانت بيانات CSV الخاصة بك تحتوي على علامات اقتباس غير مكتملة، فقد يؤدي ذلك إلى حدوث مشكلات عند محاولة قراءة أو كتابة بيانات CSV.
على سبيل المثال، ضع في اعتبارك هذه القائمة:
fruits = ['Apple', 'Ba"nana', 'Cherry']
هنا، يحتوي العنصر الثاني في القائمة على علامة اقتباس. قد يُسبب هذا مشاكل عند تحويله إلى بيانات CSV، إذ تُستخدم علامات الاقتباس لتمييز بيانات السلسلة.
الحل: إذا كنت تعلم أن بياناتك قد تحتوي على علامات اقتباس، فيمكنك استخدام معلمة quotechar عند إنشاء csv.writer لتحديد حرف مختلف لعلامات الاقتباس، أو يمكنك تجنب علامات الاقتباس أو إزالتها في بياناتك قبل التحويل إلى CSV.
فواصل غير صحيحة
يستخدم تنسيق CSV الفواصل كفاصلات بين حقول البيانات المختلفة. مع ذلك، لا تستخدم جميع بيانات CSV الفواصل. قد يستخدم بعضها علامات الجدولة أو الفواصل المنقوطة أو أحرفًا أخرى كفاصلات. إذا استخدمت الفاصل الخاطئ عند كتابة أو قراءة بيانات CSV، فقد تواجه أخطاءً أو نتائج غير متوقعة.
الحل: إذا كانت بيانات CSV الخاصة بك تستخدم فاصلًا مختلفًا، فيمكنك تحديده باستخدام معلمة الفاصل عند إنشاء csv.writer:
writer = csv.writer(output, delimiter=';')
الخلط بين التابعين ()writerow و ()writerows
تُستخدم دالة writerow()
لكتابة صف واحد، بينما تُستخدم دالة writerows()
لكتابة صفوف متعددة. قد يؤدي الخلط بين هاتين التابعين إلى نتائج غير متوقعة.
الحل: استخدم writerow عندما تريد كتابة صف واحد (يجب أن يكون قائمة واحدة)، واستخدم writerows عندما تريد كتابة صفوف متعددة (يجب أن تكون قائمة من القوائم).
يُعد تحويل قوائم بايثون إلى سلاسل CSV مهمة شائعة في معالجة البيانات ومعالجتها. توفر مكتبة CSV المدمجة في بايثون مجموعة قوية ومتعددة الاستخدامات من الدوال لتسهيل هذه العملية.
في هذه المقالة، شرحنا الخطوات المطلوبة لإجراء مثل هذه التحويلات، بدءًا من فهم قوائم Python وملفات CSV، ومكتبة csv في Python، وعملية التحويل لكل من القوائم البسيطة وقوائم القواميس، وحتى الموضوعات المتقدمة المتعلقة بهذه العملية.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.