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

Gra w życie, zrozumienie 1 linijki

Object Storage Arubacloud
+1 głos
523 wizyt
pytanie zadane 7 lutego 2018 w Python przez Wilier Bywalec (2,570 p.)
otwarte ponownie 11 lutego 2018 przez Wilier

Hej, 

na tej stronie znajduje się program Gra w Życie napisany w języku python. 

http://usingpython.com/dl/GameOfLife.py

Moje pytanie dotyczy ostatniej lijki w głónej pętli for 

thisGen, nextGen = nextGen, thisGen

Dlaczego do nextGen jest przypisywany thisGen? Przecież w kolejnej iteracji nextGen jest wykorzystywana tylko w funkcji processNextGen i tam jej wartosci są nadpisane. Każda wartość jest ponownie przeliczona. 

zapisując thisGen= nextGen, program nie będzie działać poprawnie 

4 odpowiedzi

0 głosów
odpowiedź 11 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
wybrane 11 lutego 2018 przez Wilier
 
Najlepsza
Aby obliczyć stan nowej generacji, powinieneś mieć gdzieś stan starej. W processNextGen(...) masz aktualizację nextGen. Linijka którą podałeś, zamienia dwie zmienne i jest częstym idiomem języka Python.

Przykład trochę szkolnie napisany (jakby programista C uczył się pisać w Pythonie), ale jako etap nauki ok :-)
komentarz 11 lutego 2018 przez Wilier Bywalec (2,570 p.)

Nie rozumiesz o co mi chodzi. Z technicznego punktu widzenia rozumiem co tam się dzieje, znam ten zapis. 

Nie wiem tylko po co jest ta operacja. 

Na mój rozum.

Drukuję thisGen -> obliczam nextGen -> przypisuję nextGen do thisGen -> drukuję thisGen i tak dalej. 

nextGen nigdzie nie jest wykrozystywana, do żadnych obliczeń, jest ona brana do funkcji processNextGen next[i][j] = processNeighbours(i, j, cur) ale przecież tutaj każda wartość jest wyliczana na nowo wiec bez znaczenia czy jest to stan poprzedniej generacji czy losowo zainicjowana plansza 

komentarz 11 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
edycja 11 lutego 2018 przez mokrowski

Ok. poparz na pętlę.. 

Raz zainicjowana plansza (czyli thisGen) jest drukowana.

Następnie jest obliczana nextGen na podstawie thisGen i reguł ( 

processNextGen(COLS, ROWS, thisGen, nextGen) )

Przysypiamy na chwilę 

Zamieniamy miejscami thisGen z nextGen :-) 

 

Do wgrania pralka z napędem ręcznym. Jak wrócimy do pętli, co będzie drukowane? :-) Ano to co było w nextGen a teraz (po linijce 

thisGen, nextGen = nextGen, thisGen) jest w thisGen :-)

Comprende? :-)

 

A może nie zauważyłeś że to wszystko dzieje się na referencjach? Python pracuje na referencjach (w skrócie). Dane listy przesłane jako argument do funkcji i w niej zmodyfikowane są widoczne już poza nią.

komentarz 11 lutego 2018 przez Wilier Bywalec (2,570 p.)

Ja rozumiem każdy krok pętli. Nie w tym rzecz.

Wiem czemu zmiennej thisGen należy przypisać nextGen. Moje pytanie jest czemu nie robimy tego operacją thisGen= nextGen i tylko tyle. Dlaczego zmiennej nextGen przypisujemy również thisGen. Zobacz, że kolejna iteracja pętli to będzie wydrukowanie thisGen(tej nowo obliczonej, do ktorej przed momentem wpisalismy nextGen). A teraz obliczamy kolejną nextGen - dzieje się to w linijce next[i][j] = processNeighbours(i, j, cur)  tutaj każde polenextGen dostaje nowe wartości. Dlaczego więc w operacji poprzedniej zapisywałem nextGen = thisGen? Przecież ona i tak zostanie nadpisana tymi nowymi wartościami.

komentarz 11 lutego 2018 przez mokrowski Mędrzec (155,460 p.)

A to jest akurat proste pytanie. Dlatego że nie chcemy budować pracowicie znowu nowej struktury X x Y czyli listy dwuwymiarowej :-) Mylące jest to że 2 razy występuje (bez sensu) inicjalizacja 2 list 2-wymiarowych wartościami losowymi. Ale tak się składa że w tym initGrid(...) jest także budowanie tych 2-wymiarowych struktur.

Tu się kłania semnatyka referencji którą ma Python. to co proponujesz dało by Ci nieoczekiwany efekt (co wnoszę po pytaniu).. 

No to mała próbka.. 

In [1]: l1 = ['a', 'b', 'c' ]

In [2]: l2 = [1, 2, 3]

In [3]: l1.append(l2)

In [4]: # Uwaga tu zaskoczenie :-)

In [5]: l2[1] = 'sruuuu'

In [6]: l1
Out[6]: ['a', 'b', 'c', [1, 'sruuuu', 3]]

In [7]: # I pewnie następne zaskoczenie...

In [8]: l1 = l2

In [9]: l1
Out[9]: [1, 'sruuuu', 3]

In [10]: l2[2] = 'siup'

In [11]: l1
Out[11]: [1, 'sruuuu', 'siup']

 

komentarz 11 lutego 2018 przez Wilier Bywalec (2,570 p.)
Bardzo dziękuję Ci za pomoc :)

Rozjaśniłeś mi sprawę. Zaczynam naukę pythona i przekazywanie argumentów przez referencję trochę mnie skołowało.
komentarz 11 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
Ok.. Poczytaj tylko trochę o tym jakie typy danych i kolekcje są "zmienialne" czyli muttable, a jakie nie... czyli immutable. Te dwie kategorie typów inaczej się zachowują. IMHO większość podręczników/tutoriali nie dość wyraźnie to akcentuje a pomaga to zrozumieć co się dzieje z bardziej skomplikowanymi konstrukcjami.

https://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747
0 głosów
odpowiedź 11 lutego 2018 przez Wilier Bywalec (2,570 p.)
Czy ma ktoś jakiś pomysł?
0 głosów
odpowiedź 11 lutego 2018 przez Wiciorny Ekspert (269,710 p.)

Bo jeśli to jest pętla, to po przypisaniu na starcie pętli w kolejnej iteracji nextGen- jest  na nowo " przypisujesz mu nextGen który jest po za pętlą., czyli coś na bazie zresetowania'

 

thisGen = []
nextGen = []
printGen(COLS, ROWS, thisGen, gens)
processNextGen(COLS, ROWS, thisGen, nextGen) 
// od drugiego np obiegu to bedzie ten zielony 

thisGen, nextGen = nextGen, thisGen 
// nextGen to jest ten z góry na czerwono

 

Dzieje się tak daltego, zę funkcje mimo iż się wykonują nic nie zwracają więc działają LOKALNIE, w pętli 

 

komentarz 11 lutego 2018 przez Wilier Bywalec (2,570 p.)

Ale zwróć uwagę, że funkcja  processNextGen wykorzystuję nextGen tylko jako listę do której przypisze nowo obliczone wartości w funkcji processNeighbours(). Przecież ta lista nextGen może być teraz zainicjowana losowymi wartosciami bo i tak jej [i][j] są nadpisane. 

0 głosów
odpowiedź 11 lutego 2018 przez Milesq Nałogowiec (32,020 p.)
do kodu nie zajrzałem ale to najprawdopodobniej zamiana pokolenia

do bieżącego pokolenia przypisujesz następne pokolenie a do następnego bieżące pokolenie.

potem pewnie są wykonywane jakieś operacje na następnym pokoleniu tak aby było następnym a nie; jak do tej pory; ostatnim pokoleniem
komentarz 11 lutego 2018 przez Wilier Bywalec (2,570 p.)
doskonale wiem co to jest za operacja ale ona według mnie nie ma sensu, bo w funkcji procesNextGen dokladnie ta lista jest nadpisywana nowymi wartościami
komentarz 11 lutego 2018 przez Wiciorny Ekspert (269,710 p.)
lista która jest wykorzystana w pętli, w każdej iteracji masz 'NOWĄ LISTĘ' :) gdyby nie ta operacja, modyfikowałbyś ciągle to samo

Podobne pytania

+2 głosów
2 odpowiedzi 2,346 wizyt
pytanie zadane 12 czerwca 2018 w Inne języki przez lucelka Początkujący (260 p.)
+1 głos
4 odpowiedzi 1,275 wizyt
pytanie zadane 3 grudnia 2019 w C i C++ przez PirchHD Obywatel (1,730 p.)
+1 głos
1 odpowiedź 140 wizyt
pytanie zadane 19 lipca 2021 w Python przez Maciek06 Użytkownik (680 p.)

92,556 zapytań

141,403 odpowiedzi

319,560 komentarzy

61,942 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!

...