• 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

Object Storage Arubacloud
0 głosów
148 wizyt
pytanie zadane 8 czerwca 2021 w Python przez KerivePL Początkujący (310 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 2021 przez edutomek Dyskutant (8,380 p.)
wybrane 8 czerwca 2021 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 2021 przez KerivePL Początkujący (310 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 2021 przez edutomek Dyskutant (8,380 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 2021 przez KerivePL Początkujący (310 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
2 odpowiedzi 233 wizyt
pytanie zadane 20 kwietnia 2022 w Python przez kacper1445 Gaduła (4,880 p.)
0 głosów
0 odpowiedzi 294 wizyt
pytanie zadane 26 kwietnia 2019 w Java przez modsell Nowicjusz (120 p.)
+1 głos
1 odpowiedź 718 wizyt
pytanie zadane 2 października 2021 w Python przez jakubjordanek Obywatel (1,320 p.)

92,551 zapytań

141,399 odpowiedzi

319,529 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...