Ali Ali38 نشر 16 سبتمبر 2022 أرسل تقرير نشر 16 سبتمبر 2022 السلام عليكم، لدي مصفوفة من العناصر و كل عنصر من الممكن أن يكون بحد ذاته مصفوفة، و ذلك يتكرر إلى عمق غير معروف. أي مثلاً هذه المصفوفة a = [[1, 2], [3, 4, [5, 6, [7]], 8], 9, [10, 11, [12, [13, [14], 15], 16], 17]] أي أن الدخل سيكون مثل المصفوفة السابقة و علي فكها إلى مصفوفة واحدة من الأرقام. أعلم كيفية حل المشكلة السابقة باستعمال تابع يستدعي نفسه، و لكن هل هنالك طريقة أخرى أو تابع جاهز يقوم بذلك؟ 2 اقتباس
1 Kais Hasan نشر 16 سبتمبر 2022 أرسل تقرير نشر 16 سبتمبر 2022 في أغلب الأحيان يمكن تحويل نفس الفكرة الخاصة بالتابع الذي يستدعي نفسه إلى حلقة تكرارية. يمكننا أن نقوم بالعمليات مستوى مستوى، أي أن نقوم في البداية بفك أول مستوى ثم ثاني مستوى و هكذا حتى النهاية. كيف سنعلم أننا انتهينا؟ يمكننا تخزين ذلك في متحول في حال قمنا بفك أي شيء نقوم بإسناد قيمة معينة إليه تدلنا على ذلك، و في حال انتهينا و لم نسند له شيء فهذا يدل على أننا لم نقم بفك أي مصفوفة و بالتالي انتهينا من فك كل المستويات. أحد الطرق لكتابة الكود السابق هو كالتالي: a = [[1, 2], [3, 4, [5, 6, [7]], 8], 9, [10, 11, [12, [13, [14], 15], 16], 17]] while True: flg = True new_a = [] for item in a: if type(item) is list: flg = False new_item = item else: new_item = [item] new_a.extend(new_item) a = new_a if flg: break print(a) هنا نقوم بكتابة حلفة لا نهائية أي أنها ستظل تكرر نفسها، و لكن سنستعمل break لإيقافها عند تحقق شرط ما. في البداية نقوم بتخزين قيمة True في متحول للدلالة على أننا انتهينا، و في حال قمنا بأي تعديل سنعدل قيمته إلى False أي أننا لم ننته. أيضاً نقوم بتعريف مصفوفة جديدة لتخزين الناتج فيها. بعد ذلك من أجل كل عنصر في المصفوفة الأصلية، في حال كان النمط الخاص بهذا العنصر هو list نقوم بتعديل قيمة flg إلى False للدلالة على أننا سنحتاج إلى فك عنصر و نترك العنصر كما هو (سنرى لماذا بعد قليل). في حال لم يكن list فنقوم بوضعه في list. لقد قمنا بالعملية السابقة لتسهيل كيفية الإضافة إلى المصفوفة الجديدة، حيث يمكننا الآن استدعاء التابع extend فقط، و هو سيضيف كافة العناصر إلى المصفوفة الجديدة، أي في حال كان العنصر بالأصل list سيقوم بإضافة العناصر داخل هذه ال list و في حال لم يكن كذلك سيضيف العنصر كما هو. في النهاية نقوم بتحديث المصفوفة a إلى المصفوفة الجديدة, و نختبر فيما إذا كان يجب علينا إنهاء الحلقة أم لا. بالطبع يمكننا تحسين الكود السابق ليصبح أسرع، سأترك لك هذه المهمة لتحاول فيها و يمكنك السؤال مجدداً في حال لم تستطع ذلك. 1 اقتباس
1 علي عبد محسن نشر 16 سبتمبر 2022 أرسل تقرير نشر 16 سبتمبر 2022 الحل الأمثل في مثل هذه الحالة هو إستعمال recursive method طالما أن نوع السلسلة متعدد المستويات من العمق multiple levels depth. إليك المثال التالي my_list = [[1, 2], [3, 4, [5, 6, [7]], 8], 9, [10, 11, [12, [13, [14], 15], 16], 17]] def flatten(L): if not isinstance(L,(list)): # إذا لم يكن المدخل الحالي قيد المعالجة من النوع سلسلة yield L # generator object نعيد return for F in L: # نمر في حلقة تكرار على المدخل yield from flatten(F) # نعيد الناتج ونستمر بالإرجاع لحين المرور على جميع العناصر flat= list(flatten(my_list)) # نستدعي الدالة ونحول الى سلسلة لا يوجد طريقة مسبقة التعريف تقوم بهذه المهمة ولكن هذه الطريقة الأكثر كفاءة. اقتباس
السؤال
Ali Ali38
السلام عليكم،
لدي مصفوفة من العناصر و كل عنصر من الممكن أن يكون بحد ذاته مصفوفة، و ذلك يتكرر إلى عمق غير معروف.
أي مثلاً هذه المصفوفة
أي أن الدخل سيكون مثل المصفوفة السابقة و علي فكها إلى مصفوفة واحدة من الأرقام.
أعلم كيفية حل المشكلة السابقة باستعمال تابع يستدعي نفسه، و لكن هل هنالك طريقة أخرى أو تابع جاهز يقوم بذلك؟
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.