سؤال

هل تتكرر الخريطة () من خلال القائمة مثل "من أجل"؟هل هناك قيمة في استخدام الخريطة مقابل؟

إذا كان الأمر كذلك، فإن الكود الخاص بي يبدو الآن كما يلي:

for item in items:
    item.my_func()

إذا كان الأمر منطقيًا، أود أن أجعله خريطة ().هل هذا ممكن؟ما هو المثال مثل؟

هل كانت مفيدة؟

المحلول

يمكنك استخدام map بدلا من ال for الحلقة التي أظهرتها، ولكن نظرًا لأنك لا يبدو أنك تستخدم نتيجة item.my_func(), ، هذا هو لا ينصح. map يجب استخدامه إذا كنت تريد تطبيق وظيفة دون آثار جانبية على جميع عناصر القائمة.في جميع المواقف الأخرى، استخدم حلقة for صريحة.

أيضًا اعتبارًا من Python 3.0 map إرجاع مولد، وذلك في هذه الحالة map لن تتصرف بنفس الطريقة (إلا إذا قمت بتقييم جميع العناصر التي أرجعها المولد بشكل صريح، على سبيل المثال.بالاتصال list عليه).


يحرر: kibibu يسأل في التعليقات لتوضيح السبب mapلا ينبغي أن تكون الوسيطة الأولى دالة ذات آثار جانبية.سأحاول الإجابة على هذا السؤال:

map من المفترض أن يتم تمرير وظيفة f بالمعنى الرياضي.في مثل هذه الظروف لا يهم في أي ترتيب f يتم تطبيقه على عناصر الوسيطة الثانية (طالما أنها عاد بترتيبها الأصلي بالطبع).والأهم من ذلك، في ظل تلك الظروف map(g, map(f, l)) يعادل لغويا ل map(lambda x: g(f(x)), l), بغض النظر عن الترتيب الذي f و g يتم تطبيقها على المدخلات الخاصة بكل منها.

على سبيل المثال، لا يهم ما إذا كان map العوائد والمكرر أو القائمة الكاملة في وقت واحد.ومع ذلك، إذا f و/أو g تسبب آثارًا جانبية، فإن هذا التكافؤ لا يكون مضمونًا إلا إذا كانت دلالاته map(g, map(f, l)) هي تلك التي في أي مرحلة g يتم تطبيقه على الأول ن العناصر التي تم إرجاعها بواسطة map(f, l) قبل map(f, l) ينطبق f إلى (ن + 1)العنصر الأول من l.(وهذا يعني أن map يجب إجراء التكرار الأكثر كسلًا — وهو ما يحدث في Python 3، ولكن ليس في Python 2!)

الذهاب خطوة أخرى إلى الأمام:حتى لو افترضنا تنفيذ Python 3 لـ map, ، قد ينهار التكافؤ الدلالي بسهولة إذا كان الناتج map(f, l) على سبيل المثالمر من خلال itertools.tee قبل أن يتم توريدها إلى الخارج map يتصل.

قد تبدو المناقشة أعلاه ذات طبيعة نظرية، ولكن عندما تصبح البرامج أكثر تعقيدًا، تصبح أكثر صعوبة في التفكير وبالتالي يصعب تصحيح أخطائها.إن التأكد من ثبات بعض الأشياء يخفف من هذه المشكلة إلى حد ما، وقد يمنع في الواقع فئة كاملة من الأخطاء.

أخيرا، map يذكر الكثير من الناس بنظيره الوظيفي الحقيقي في مختلف اللغات الوظيفية (البحتة).إن تمريرها على أنها "وظيفة" ذات آثار جانبية سوف يربك هؤلاء الناس.لذلك، فإن رؤية البديل (أي استخدام حلقة صريحة) ليس أصعب في التنفيذ من استدعاء map, ، يوصى بشدة بتقييد استخدام map لتلك الحالات التي لا تسبب فيها الوظيفة المراد تطبيقها آثارًا جانبية.

نصائح أخرى

ويمكنك إرسال هذه الخريطة باستخدام مثل هذا:

map(cls.my_func, items)

واستبدال CLS مع فئة من العناصر التي يتم بالتكرار عبر.

وكما ذكر Stephan202، وهذا هو على لا ينصح في هذه الحالة.

وكقاعدة عامة، إذا كنت ترغب في إنشاء قائمة جديدة من خلال تطبيق بعض من وظيفة إلى كل عنصر في القائمة، استخدم خريطة. هذا وقد وينطوي هذا يعني أن وظيفة لها أي أثر جانبي، وبالتالي هل يمكن (يحتمل) تشغيل الخريطة في نفس الوقت.

إذا كنت لا تريد إنشاء قائمة جديدة، أو إذا كانت وظيفة لديها آثار جانبية، واستخدام للحلقة. هذا هو الحال في المثال الخاص بك.

وهناك فرق طفيف الدلالي، التي ربما أغلقت في المواصفات لغة بايثون. و<م> خريطة هو موازاة صراحة، في حين <م> ل فقط في حالات خاصة. يمكن كود <م> كسر الخروج من ل ، ولكن الهروب فقط مع استثناء من خريطة .

في رأيي <م> خريطة لا ينبغي أيضا ضمان النظام من تطبيق وظيفة في حين <م> ل لا بد منه. AFAIK عدم تنفيذ الثعبان هو حاليا قادرة على القيام بذلك لصناعة السيارات في الموازاة.

ويمكنك التبديل map لديك إلى إطار عمل الحوسبة الخيوط أو متعدد المعالجة أو توزيع باردا إذا كنت في حاجة إليها. ديسكو مثال يقاوم وقوع إطار الموزعة، إرلانج وبيثون القائمة. I تكوينه في 2 صناديق من 8 النوى، والآن يعمل برنامجي 16 مرات أسرع، وذلك بفضل مجموعة ديسكو، ولكن كان لي لكتابة برنامجي من comprehensions قائمة وحلقات لتعيين / الحد.

وانها نفس الصفقة لكتابة البرنامج باستخدام لحلقات وcomprehensions قائمة وخريطة / تقليل، ولكن عندما كنت في حاجة إليها لتشغيل على كتلة، يمكنك أن تفعل ذلك تقريبا مجانا إذا كنت تستخدم خريطة / تقليل. إذا كنت لا، حسنا، سوف تضطر إلى إعادة كتابة.

وحذار: بقدر ما أعرف، الثعبان الإصدار 2.x بإرجاع قائمة بدلا من مكرر من الخريطة. لقد سمعت هذا يمكن تجاوزه باستخدام iter.imap() (لم تستخدم قط أنه على الرغم من).

استخدم صريحة للحلقة عندما لم يكن في حاجة إلى قائمة من النتائج مرة أخرى (على سبيل المثال. وظائف مع آثار جانبية).

استخدم الفهم القائمة عندما كنت في حاجة قائمة النتائج مرة أخرى (على سبيل المثال الوظائف التي ترجع قيمة تستند مباشرة على المدخلات).

استخدم خريطة () عندما كنت في محاولة لإقناع المستخدمين اللثغة أن بيثون الجدير تستخدمه. ؛)

ووالميزة الرئيسية لmap هي عندما تريد الحصول على النتيجة من بعض الحساب على كل عنصر في القائمة. على سبيل المثال، وهذا المقتطف يتضاعف كل قيمة في القائمة:

map(lambda x: x * 2, [1,2,3,4])  #=> [2, 4, 6, 8]

ومن المهم أن نلاحظ أن map إرجاع قائمة جديدة مع النتائج. لم تقم بتعديل القائمة الأصلية في المكان.

لتفعل الشيء نفسه مع for، سيكون لديك لإنشاء قائمة فارغة وإضافة خط اضافي للجسم for لإضافة نتيجة كل حساب على القائمة الجديدة. النسخة map هو أكثر إيجازا والوظيفية.

خريطة يمكن في بعض الأحيان يكون أسرع لالمدمج في وظائف من الترميز ويدويا للحلقة. محاولة توقيت خريطة (شارع، ومجموعة (1000000)) مقابل مماثلة للحلقة.

map(lambda item: item.my_func(), items)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top