• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Usuwanie elementów list - prośba o wytłumaczenie działania

Fiszki IT
Fiszki IT
0 głosów
37 wizyt
pytanie zadane 8 czerwca w Python przez KerivePL Początkujący (270 p.)

Jestem po maturze z informatyki, pisałem w pythonie, podczas nauki operowałem ciągle na listach bo wydawały mi się ona najłatwiejsze. Zaznaczę że jestem samoukiem, więc możliwe że niechcący podczas edukacji pominąłem jakieś ważne informacje.

Teraz robiłem projekt hobbystycznie i jedna funkcja mi nie działała jak sobie życzyłem. Wyeksportowałem kluczowe elementy do osobnego pliku i naprawiłem program, ale znalazłem coś czego nie rozumiem.

Na potrzebę przykładu uprościłem funkcję, więc może wydawać się sposób trywialny, ale istota problemu jest dobrze ukazana. Funkcja miała kopiować ostatni element, umieszczać go zmienionym na końcu listy a następnie usuwać pierwszy element.

def move(ghost_stats):
    head=ghost_stats[-1]
    head+=1
    ghost_stats.append(head)
    ghost_stats=ghost_stats[1:]
    return ghost_stats
    
def main():
    ghost_stats=[7,8,9,10]
    for i in range(5):
        print(move(ghost_stats))
main()

konsola:

[8, 9, 10, 11]
[8, 9, 10, 11, 12]
[8, 9, 10, 11, 12, 13]
[8, 9, 10, 11, 12, 13, 14]
[8, 9, 10, 11, 12, 13, 14, 15]

Zastosowałem list=list[1:] . Czemu pierwszy element się nie usuwa? Zapewnie nie rozumiem dokładnego działania list w pythonie, ale przeszukując internet nikt mi tego dobrze nie wyjaśnił.

Z problemem sobie poradziłem oczywiście, stosując (zamiast list=list[1:]) 

ghost_stats.remove(ghost_stats[0])

Prosiłbym o wytłumaczenie mojego błędu w postrzeganiu list.

Dziękuję z góry za pomoc

1 odpowiedź

+4 głosów
odpowiedź 8 czerwca przez edutomek Mądrala (5,200 p.)
wybrane 8 czerwca przez KerivePL
 
Najlepsza

Zapewne chodziło Ci o coś takiego (wiersz 11):

def move(ghost_stats):
    head=ghost_stats[-1]
    head+=1
    ghost_stats.append(head)
    ghost_stats=ghost_stats[1:]
    return ghost_stats
     
def main():
    ghost_stats=[7,8,9,10]
    for i in range(5):
        ghost_stats = move(ghost_stats)
        print(ghost_stats)
main()

Operacje na listach rozumiesz dobrze.
Natomiast możesz mieć pewien problem ze zrozumieniem referencji/obiektów oraz ich zasięgu.

W funkcji masz obiekt ghost_stats.
Obiekt ten zmieniasz (`ghost_stats.append(head)`) - stąd w konsoli lista się powiększa, co widać.

Natomiast potem, otrzymany obiekt (a właściwie to referencję na obiekt), ZASTĘPUJESZ nowym:

`ghost_state = ghost_stats[1:]`

Uwaga: zastępujesz obiekt tylko w funkcji `move` - a nie w Twojej pętli!

Innymi słowy, Twoja funkcja modyfikuje listę i ją zwraca - ale Ty nigdzie z tej zwróconej wartości nie robisz żadnego użytku (poza wypisaniem wyniku w konsoli).

Spróbuj, dla ćwiczenia, zmienić nazwę parametru w funkcji move z "ghost_stats" na cokolwiek innego (np. na "funny_list"). Funkcja powinna działać tak samo, prawda? Przecież nazwa zmiennej nie ma znaczenia... Proponuję to, bo podejrzewam, że zasugerowałeś się nazwą zmiennej w funkcji, którą pomyliłeś z nazwą innej zmiennej w Twoim kodzie.

komentarz 9 czerwca przez KerivePL Początkujący (270 p.)

Dziękuję za pomoc.

Od razu rodzą mi się kolejne pytania. Dlatego list.append list.remove itd działają w funkcji-matce, natomiast list=list[1:] już nie. Zapewne jest to coś oczywistego ale ja niestety kropek nie łączę. Jeżeli masz linka gdzie to jest dobrze wytłumaczone to daj proszę znać.

1
komentarz 9 czerwca przez edutomek Mądrala (5,200 p.)
Linka nie mam. (Zresztą gdybym miał, to raczej po angielsku...) Może jakoś spróbuję...

Referencje, referencje...

To działa wszędzie - w każdej funkcji.

Załóżmy, że masz jakiś obiekt (konkretnie - listę): l = [1, 2, 3].

I teraz: robisz l.append(4).

Co się dzieje? Modyfikujesz listę, dodając na końcu wartość 4. Po tej operacji l = [1, 2, 3, 4].

Z remove jest analogicznie - tylko elementy są usuwane. Ot, zwykłe operacje wykonywane NA OBIEKTACH.

ALE: jak mamy listę l = [1,2,3] i zrobimy PRZYPISANIE: l = l[1:], to dzieje się coś innego.

Obiekt oryginalny (czyli lista [1,2,3]) pozostaje niezmieniony. Natomiast powstaje nowy obiekt (też lista) - [2,3]. Ten nowy obiekt jest przypisywany do zmiennej l. A więc po tej operacji l = [2,3] - ale to jest już nowy obiekt.

Co się dzieje ze starym (tą oryginalną listą [1,2,3])?

To zależy. Jeśli nie ma już na niego referencji, to może zostać usunięty. Jeśli są referencje, to wciąż będzie istniał.

I teraz najważniejsze: jak przekazujesz listę do funkcji jako parametr, to przekazujesz referencję. Czyli wykonując w tej funkcji append/remove, zmienisz ooryginalny obiekt. Natomiast po wykonaniu przypisania (a to właśnie się dzieje: wiersz piąty), masz już do czynienia z nowym obiektem. Stary pozostał bezpieczny i jest wciąż osiągalny tam, gdzie wywołałeś swoją funkcję.

Może prościej byłoby to wyjaśnić na jakiejś tablicy, ale cóż - nie mamy tablicy do pisania...

Jakbyś miał jakieś pytania, to zawsze można się ze mną umówić na konsultacje online. Cennik jest przystępny (jak dla Ciebie - 0 PLN / h), ponoć nie krzyczę za bardzo ;-)
komentarz 9 czerwca przez KerivePL Początkujący (270 p.)

Dziękuję bardzo za zrozumiałe objaśnienie oraz  chęć dalszej pomocy. Wydaje mi się że pojąłem mechaniki działania, niemniej jak znajdą się inne aspekty których nie rozumiem i nie odnajdę odpowiedzi to na pewno się zgłoszę.

Tacy ludzie w intrenecie to skarb heart

Podobne pytania

0 głosów
1 odpowiedź 198 wizyt
0 głosów
1 odpowiedź 61 wizyt
pytanie zadane 29 stycznia 2020 w Python przez kingmajster Użytkownik (520 p.)
+1 głos
2 odpowiedzi 114 wizyt
pytanie zadane 29 marca 2018 w Python przez Michał Romańczyk Początkujący (430 p.)
Porady nie od parady
Zadając pytanie postaraj się o szczegółowe opisanie problemu oraz udostępnienie wszystkich istotnych informacji (kody źródłowe, zrzuty ekranu itp.).Opisanie problemu

84,758 zapytań

133,561 odpowiedzi

295,987 komentarzy

56,012 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...