[אתגר] לסדר את הבלאגן

תגיות:

עדיין יותר רשימה חדשה בצד ימין של ההשמה :slight_smile: ו־+= בערך שקול ל־extend

בדקתי באמצעות
print("ID before: " + str(id(list3)))

והתוצאה שווה, כלומר הרשימה לא השתנת בכלל. אותו מיקום
לחלופין, ניתן גם לעשות כך:

def sort_3(list3):
    index = count1 = count2 = count3 = 0
    while index < len(list3):
        if list3[index] == 1:
            count1 += 1
        elif list3[index] == 2:
            count2 += 1
        elif list3[index] == 3:
            count3 += 1
        index += 1
    return ([1] * count1) + ([2] * count2) + ([3] * count3)

כן, אבל בצד ימין של ההשמה יצרת רשימה חדשה.
ה־+= עושה extend לרשימה המקורית (שזה חלק ממה שאסור, לפי החוקים).


בקוד שהבאת עכשיו אתה עדיין יוצר רשימה חדשה ב־return

אני מקווה שהפעם זה כבר בסדר.

def sort_3(list3):
    index = count1 = count2 = count3 = 0
    while index < len(list3):
        if list3[index] == 1:
            count1 += 1
        elif list3[index] == 2:
            count2 += 1
        elif list3[index] == 3:
            count3 += 1
        index += 1
    list3[:] = [1] * count1
    list3[count1:] = [2] * count2
    list3[count1+count2:] = [3] * count3
    return list3

זה לא איזה מעקף שאתה צריך לעשות, זה פשוט שינוי של האלגוריתם.
כל פעם שאתה כותב [item], אתה יוצר רשימה חדשה שיש בה את item.
חריג למקרה זה כשאתה כותב l[item], שזה "גש לרשימה הקיימת l במקום item.

אז יש כאן איזה חוסר הבנה בסיסית שלי, כי אם כך אני לא מבין למה כשאני בודק לפני ואחרי באמצעות:

print("ID before: " + str(id(list3)))
print("ID after: " + str(id(list3)))

אני מקבל תוצאות זהות? לשיטתך אני אמור לקבל תוצאות שונות לא כך?

אתה יוצר רשימה חדשה, ואז מוסיף לרשימה הישנה את האיברים מהרשימה החדשה וזורק את הרשימה החדשה :slight_smile:

לייק 1
def sort_3(l):
    i = 0
    first_two = first_three = 0
    while i < len(l):
        if l[i] == 1:
            if i > first_three or i > first_two:
                l[i] = l[first_three]
                l[first_three] = l[first_two]
                l[first_two] = 1
            i += 1
            first_two += 1
            first_three += 1
        elif l[i] == 2:
            if i > first_three:
                l[i] = l[first_three]
                l[first_three] = 2
            first_three += 1
            i += 1
        elif l[i] == 3:
            i += 1
    return l
2 לייקים

הפותר הראשון, ברכות :slight_smile:

לייק 1

רקורסיה נחשב הרצה אחת ? או שזה n הרצות ?

לא בטוח שהבנתי את השאלה כ"כ :slight_smile:

אני אפשט - מותר להשתמש ברקורסיה ? :slight_smile:

כן, אבל זה נחשב לולאה. שים לב שמותר לעבור על כל איבר רק פעם אחת :slight_smile:

אוקיי מצאתי פתרון שעובר על הרשימה רק פעם אחת ולא משתמש באף פונקציה של פייתון על רשימות אבל הוא מאוד לא אלגנטי ואני חושבת שאולי יש שם תנאים שחוזרים על עצמם ואפשר להוריד אותם (ניסיתי להוריד תנאים והגעתי ללולאות אינסופיות)… אשמח אם תוכל להגיד לי איזה חלקים אני יכולה לשנות כדי לקבל קוד יותר אלגנטי

def sort_3(list):
    i = 0
    num3 = 0
    while i < len(list) - 1:
        if list[i] == 3:
            num3 +=1
        if list[i] == 1 and i != 0:
            j = 0
            while i - 1 - j >= 0:
                temp = list[i - 1 - j]
                list[i - 1 - j] = list[i - j]
                list[i - j] = temp
                j += 1
            if list[i] == 2:
                i += 1
        elif list[i] == 3 and i != len(list) - 1:
            j = 0
            while i + 1 + j <= len(list) - 1:
                temp = list[i + 1 + j]
                list[i + 1 + j] = list[i + j]
                list[i + j] = temp
                j += 1
            if list [i] == 2:
                i += 1
        else:
            i += 1
        if i == len(list) - num3:
            break
    print (list)

רק עכשיו נחשפתי לאזור של האתגרים…
מנסה לא להסתכל על פתרונות, אז סליחה אם יש טעות שחוזרת על עצמה

לייק 1

מקובל? :thinking:

לייק 1

‏‏לכידה

ואוו לקח הרבה זמן אבל נראה לי שבסוף הצלחתי :woozy_face: