python-dirbtuves / it-brandos-egzaminai

Informacinių technologijų brandos egzaminų, programavimo praktinių užduočių sprendimai
GNU Affero General Public License v3.0
13 stars 13 forks source link

Duomenų skaitymas iš failo #3

Open sirex opened 9 years ago

sirex commented 9 years ago

Pascal kalboje, skaitymas iš failo atrodo taip:

var f : text;
    x, y : integer;

begin
    assign(f, 'U1.txt'); 
    reset(f);
    readln(f, x, y);
    close(f);
end.

Variantai naudojant Python:

Variantas 1:

with open('U1.txt') as f:
    k = int(next(f))
    for i in range(k):
        x, y = map(int, next(f).split())

Variantas 2 (keičiam next(f) į f.readline()):

with open('U1.txt') as f:
    k = int(f.readline())
    for i in range(k):
        x, y = map(int, f.readline().split())

Variantas 3 (naudojam f.read().splitlines()):

with open('U1.txt') as f:
    lines = f.read().splitlines()

k = int(lines.pop(0))
for line in lines[:k]:
    x, y = map(int, line.split())
dz0 commented 9 years ago

arba vietoj "next" http://stackoverflow.com/a/11555509/4217317

with open('filename.txt') as fp:
    for line in fp:
        print( line )
sirex commented 9 years ago

Šis variantas daugeliu atvejų netinka, kadangi užduotys parengtos pagal Pascal veikimą. T.y. užduotyse reikia nuskaityti vieną eilutę, iš jos išrinkti kintamuosius, tada remiantis tais kintamaisiais skaityti sekančias eilutes ir reikia skaityti tik tiek eilučių, kiek nurodyta.

Tai maždaug gaunasi taip:

with open('U1.txt') as f:
    k = int(next(f))
    for i in range(k):
        x, y = map(int, next(f).split())

Jei tą patį atkartoti pagal tavo pasiūlytą variantą, kodas gaunasi sudėtingokas:


with open('U1.txt') as f:
    for i, line in enumerate(f):
        if i == 0:
            k = int(line)
        elif i > k:
            break
        else:
            x, y = map(int, line.split())
dz0 commented 9 years ago

tiesa...

O gal aiškiau tuomet būtų f.readline()?
nežinau ar po jo galima tęsti su "for line in f"? ir jeigu nuskaitomi teksto duomenys, tai reik neužmiršt "\n" pabaigoje

dz0 commented 9 years ago

be to, jei į failą rašomi (gal ir skaitomi) duomenys su lietuviškom raidėm, berods reik neužmiršti ncoding="utf-8"?

dz0 commented 9 years ago

ps.: šiuolaikiniam kontekste aš tikėčiaus duomenų JSON formate..., bet čia ateičiai...

sirex commented 9 years ago

f.readline() daro tą patį ką ir next(f), tik tiek, kad su next(f), f nebūtinai turi būti file-like objektas, tai gali būtų eilučių iteratorius.

Dar vienas variantas:


with open('U1.txt') as f:
    lines = f.read().splitlines()

k = int(lines.pop(0))
for line in lines[:k]:
    x, y = map(int, line.split())

f.splitlines() grąžina sąrašą eilučių be \n simbolių.

dz0 commented 9 years ago

Readline panašu į Paskalį - lengviau atsiminti :-) On Apr 8, 2015 1:53 PM, "sirex" notifications@github.com wrote:

f.readline() daro tą patį ką ir next(f), tik tiek, kad su next(f), f nebūtinai turi būti file-like objektas, tai gali būtų eilučių iteratorius.

Dar vienas variantas:

with open('U1.txt') as f: lines = f.splitlines()

k = int(lines.pop(0))for line in lines[:k]: x, y = map(int, line.split())

f.splitlines() grąžina sąrašą eilučių be \n simbolių.

— Reply to this email directly or view it on GitHub https://github.com/python-dirbtuves/it-brandos-egzaminai/issues/3#issuecomment-90879301 .

sirex commented 9 years ago

@dz0 o ką manai apie f.read().splitlines() variantą?

sirex commented 9 years ago

f.read().splitlines() man atrodo geriausias variantas, kadangi gaunamas paprastas eilučių masyvas, be \n simbolių. Esant reikalui, galima naudoti k = int(lines.pop(0)), kad gauti visokias pradines reikšmes, vėliau tas reikšmes labai paprasta naudoti cikluose: for line in lines[:k].

dz0 commented 9 years ago

Neblogai irgi. Paprastiems atvejams (su skaiciais) geriau gal su readline... On Apr 8, 2015 2:18 PM, "sirex" notifications@github.com wrote:

f.read().splitlines() man atrodo geriausias variantas, kadangi gaunamas paprastas eilučių masyvas, be \n simbolių. Esant reikalui, galima naudoti k = lines.pop(0), kad gauti visokias pradines reikšmes, vėliau tas reikšmes labai paprasta naudoti cikluose: for line in lines[:k].

— Reply to this email directly or view it on GitHub https://github.com/python-dirbtuves/it-brandos-egzaminai/issues/3#issuecomment-90882740 .

dz0 commented 9 years ago

dar aptikau kelias svetaines programavimo mokymui, kur IO pateiktas keliomis kalbomis - gal bus į temą idėjų: pvz, https://www.hackerrank.com/challenges/solve-me-second http://www.codingame.com/ide/13044850b8764cc8e466942afd18d8d85803a37

ignaloidas commented 6 years ago

90% atvejų reikia nusiskaityti eilute į listą, kam puikiai tinka toks konstruktas:

f=open('duom.txt')
 nums=[int(x) for x in f.readline().split()]

jei reikia kelias eilutes, galima atitinkamai paruošti. f gali buti bet koks TextIOBase pagrindu sukurtas objektas. Dauguma kitų atvejų pakanka f.readline(), dar neteko susidurti kur netiktų.