اذهب إلى المحتوى
  • 0

استخدام حلقة تكرار لا يتم تطبيقها على كل العناصر في بايثون؟

Fahmy Mostafa

السؤال

أحاول إنشاء دالة تقوم بحذف كل الحروف المتحركة (aeiou) من نص مدخل إليها، لكن المشكلة هي أنه لا يتم حذف كل الحروف المتحركة، ويتبقى حرف متحرك أخير، هذا هو الكود الخاص بي:

text = "Hellooo, world! Words!"

def removeVowel(text):
    textlist = list(text.lower())

    for char in textlist:
        if char in 'aeiou':
            textlist.remove(char)

    return "".join(textlist)

print(removeVowel(text))	# hll, wrld! words!

كما تلاحظ حرف o في كلمة words لم يتم حذفه، ما الخطأ الذي أقوم به هنا؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

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

يمكن حل المشكلة بإستخدام عدد من الطرق الأخرى، مثلاً list comprehension:

def anti_vowel(c):
    vowels = ('a', 'e', 'i', 'o', 'u')         
    return ''.join([l for l in c if l not in vowels])
anti_vowel("Hellooo, world! Woooords!")
# Hll, wrld! Wrds!

الناتج عبارة عن كل الحروف و علامات الترقيم ما عدا التي تم تحديدها في vowels set.

يمكن أيضاً إستخدام regular expression، عن طريق إستخدام الدالة sub التي تقوم بالبحث عن واحد أو مجموعة حروف في نص محدد و إستبداله بما يتم تمريره في المدخل الثاني للدالة.

import re
def anti_vowel(s):
    return re.sub(r'[AEIOU]', '', s, flags=re.IGNORECASE)
anti_vowel("Hellooo, world! Woooords!")

لاحظ هنا تحديد مدخل أخير للدالة و التي يتغاضى فيها عن وجود الحروف الكبيرة أو الصغيرة (إختياري) و يبحث عن الأحرف المحددة بغض النظر عن نوعها.

الطريقة الثالثة هي إستخدام translate وهي دالة تستقبل dictionary بالحروف التي سيتم إستبدالها و القيم الجديدة لها، راجع المثال التالي:

dictionary = str.maketrans(dict.fromkeys('aeiouAEIOU'))
"Hellooo, world! Woooords!".translate(dictionary)

وفيه تم إستخدام maketrans لإنشاء mapping table من الحروف المدخلة كبيرها و صغيرها، حيث أن الحروف ستمثل المفاتيح بدون قيم values are None، و أخيراً نمرر الجدول لدالة الترجمة.

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

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

يمكن تطبيق نفس الشيفرة على المثال "oooo" مثلا الذي يحوي 4 محارف صوتية، ونتيجة التنفيذ أنه سيتم حذف فقط محرفين والنتيجة "oo" وعندها دليل الحلقة سيكون أكبر من طول المصفوفة و ستنتهي الحلقة قبل حذف كل المحارف.

الحل بتطبيق دالة الاستبدال كما في الإجابة السابقة. أو استعمال الفلتر filter:

text = "Hellooo, world! Words!"
def removeVowel(text):
    textlist = list(text.lower())
    for char in list('aeiou'):
        #textlist = [i for i in textlist if i != char]       # ممكن هذه الطريقة أيضا
        textlist = list(filter(lambda a: a != char, textlist))
    return "".join(textlist)

print(removeVowel(text))	# hll, wrld! wrds!

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

المشكلة هي أنك تقوم بإستخدام دالة ()remove من أجل إزالة الحروف المتحركة فلا تقم بإستخدامها في قائمة بينما تقوم بالتكرار فيها

يمكنك إستخدام دالة ()replace كما في هذا الكود للحصول على النتيجة المرغوبة

text = "Hellooo, world! Words!"

def anti_vowel(c):
    newstr = ""
    # الحروف المتحرك
    vowels = ('a', 'e', 'i', 'o', 'u')
    for x in c.lower():
        # فحص إذا كان هناك حرف متحرك
        if x in vowels:
            # إزالة الحرف المتحرك
            newstr = c.replace(x, "")
            #إرجاع النص الجديد الخالي من الحروف المتحركة
    return newstr

print(anti_vowel(text))

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

بإمكانك إستخدام التعابير النمطية لحذف كل الحروف المتحركة (aeiou):

import re

def removeVowel(text):
    result = re.sub(r'[AEIOU]', '', text, flags=re.IGNORECASE)
    return result

text = "Hellooo, world! Words!"
print(removeVowel(text)) # Hll, wrld! Wrds!

أو تعكس الأمر فبدل ما تحذف تضيف تعمل حلقة للدوران على كل الحروف و إذا لم يكن الحرف ينتمي إلى الحروف aeiou تُضيفه إلى سلسلة نصية تكون مُهيئة ب "" مثال:

def removeVowel(text):
    return ''.join([l for l in text if l not in "aeiouAEIOU"]);

text = "HeElloooOOO, world! WoOrds!"
print(removeVowel(text)) # Hll, wrld! Wrds!
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...