Sposoby odczytywania danych z pliku - różnice

0
students = []


def read_file():
    try:
        f = open("students.txt", "r")
        for student in read_students(f): # lub (2) "for student in f" lub (3) "for student in f.readlines()"
            students.append(student)
        f.close()
    except Exception:
        print("Could not read a file.")


def read_students(f):
    for line in f:
        yield line

Witam,

  1. Pierwsze pytanie, jaka jest różnica między pierwszym sposobem dołączania linii pliku do listy, a drugim (2), poza tym, że drugi używa własnej funkcji? Skutek jest taki sam. Poza tym z tego co mi wiadomo for działa z listami i generatorami, a f przechowuje plik.

  2. Druga sprawa, z moich testów wynika, że funkcja po słowie kluczowym in w pętli for jest wywoływana jeden raz (moja teza). Dlaczego więc pętla ta spełnia swoją funkcję z generatorem? Z tego co czytałem to yield powoduje, że funkcja się zatrzymuje, zapisuje punkt, w którym się zatrzymała oraz zwraca określoną wartość. Zatem kłóci się to z moją tezą, ponieważ przypisane zostają wszystkie linie z pliku tekstowego do listy students.

  3. Dlaczego print(read_students("test") nie wyswietla "test", tylko adres pamięci (o ile dobrze pamiętam), a w petli jest inaczej? Zapewne yield działa trochę inaczej niż ja zakładam.

  4. Trzeci sposób dołączania linii do listy jest błędny/mało efektywny, bo w czasie działania pętli for pamięć RAM musi przechowywać wszystkie linie tekstu na raz?

Proszę o wyjaśnienie i wyrozumiałość z uwagi na to, że Pythona uczę się od kilku dni.
Z góry dziękuję za odpowiedź.

Pozdrawiam

1
  1. a 2. różnie się tym, że w 1 masz nie potrzebną funkcję, która robi Ci to samo co iterowanie w liście.
    Generalnie przekazujesz listę i tworzysz z niej generator co w tym przypadku nie ma sensu bo nie zaoszczędzisz w ten sposób pamięci ani czasu.

Tak f przechowuje plik ale to jest klasa. Klasa ta posiada metody pozwalające na iterowanie po niej za pomocą for in

  1. Tworzysz generator za pomocą read_students(f) i iterujesz po jego wszystkich elementach. Dlatego nie masz jednego elementu w studends tylko wszystkie. Bo bierzesz wszystkie.

  2. read_students('test') zwraca generator. Printujesz go więc pokazuje Ci m.in adres jego pamięci. Żeby wyświetlić coś z wnętrza iteratora musisz go np. przeiterować czyli zrobić pętlę na nim lub użyć specjalnych metod do tego.

  3. Tak będziesz miał cały plik w pamięci. Przy małych plikach nie ma co się tym przejmować.

1 użytkowników online, w tym zalogowanych: 0, gości: 1