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

question-closed Pętla for wykonuje się połowe razy

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
293 wizyt
pytanie zadane 7 października 2020 w Python przez Dawid Popławski Nowicjusz (160 p.)
zamknięte 17 grudnia 2020 przez Dawid Popławski
sciezka = "Dane_PR\liczby.txt"
plik = open(sciezka, "r")

zera = 0
jedynki = 0
wynik = 0
i = 0
#j = 0
#while j != 1000:
for j in plik: #Przelatuje jedynie 500 razy zamiast 1000
    tekst = plik.readline()
    dlugosc = len(tekst)
    
    for i in range(0, dlugosc):
        if(tekst[i] == '0'):
            zera += 1
        if(tekst[i] == '1'):
            jedynki += 1
    if(zera > jedynki):
        wynik += 1
    zera = 0
    jedynki = 0
   # i += 1

print(wynik)

W pliku liczby.txt znajduje się 1000 liczb naturalnych zapisanych binarnie. Każda liczba zapisana jest w osobnym wierszu. Podaj, ile liczb z pliku liczby.txt ma w swoim zapisie binarnym więcej zer niż jedynek.

W poleceniu mam podane, że plik zawiera 1000 liczb, jednak chciałbym żeby pętla przeleciałą przez cały plik niezależnie od jego długości. Nie rozumiem dlaczego tak się nie dzieje, skoro

linia = 0
for j in plik:
    linia += 1

zwraca 1000

Matura 2015 maj. Rozwiązania na dole

komentarz zamknięcia: rozwiążane
komentarz 7 października 2020 przez Benek Szeryf (92,970 p.)

Wiem, że nie o to pytasz, ale Twój kod przypomina bardziej C/C++. Taki typowy kod z wykorzystaniem mechanizmów Pythona będzie bardziej przypominał coś takiego:

with open('liczby.txt', 'r') as f:
    print(len([_ for i in f.read().strip('\n').split('\n') if i.count('0') > (len(i)//2)]))

 

komentarz 7 października 2020 przez Dawid Popławski Nowicjusz (160 p.)
Dopiero co przerzuciłem się na Pythona z c++. Adrian rozjaśnił mi sytuacje.
komentarz 7 października 2020 przez mokrowski Mędrzec (156,320 p.)

Hmm..

print(sum([word.count('0') > word.count('1') for word in open('slowa.txt')]))

 

komentarz 8 października 2020 przez Benek Szeryf (92,970 p.)
Menadżer kontekstu by się jednak przydał.
komentarz 8 października 2020 przez mokrowski Mędrzec (156,320 p.)
A w jakim celu? Zasięg istnienia obiektu pliku jest do granicy funkcji. Destrukcja obiektu zapewnia poprawne zamknięcie. Także 1(int) -> True (bool) jest w standardzie języka. Zbędne jest także rozbijanie na listę (.split(..)) bo .count(..) robi co trzeba. Oczywiście przykład bazuje na poprawnych danych. Napisany produkcyjnie wymagał by obsługi wszystkich błędów i nieco bardziej "gadatliwego kodu".
komentarz 8 października 2020 przez Benek Szeryf (92,970 p.)
W celu poprawnego zamknięcia pliku na wypadek błędów.

Rozważałem dwukrotne użycie count, tak jak Ty, ale postanowiłem zastąpić je len, które ma złożoność obliczeniową O(1). Wygenerowałem sobie pliki po 1000 linii z losowymi 0 oraz 1 i się potwierdziło, że moje rozwiązanie jest trochę szybsze niż Twoje, 0.7:1.0. Oczywiście Twój kod jest bardziej czytelny.
komentarz 8 października 2020 przez mokrowski Mędrzec (156,320 p.)
Hmm.. Jeśli by wyciskać lepszą wydajność, to skończyło by się buforowanym wejściem i bardziej wyrafinowanym zliczaniem. Dla Python'a to (w mojej ocenie) jednak trochę sztuczne. Dla wydajności z całą pewnością C/C++ byłby lepszy. Wraz z mechanizmami systemowymi przyśpieszającymi obsługę plików.

Nikt nie wymaga od F1 by posiadała kierunkowskazy a od Harleya by miał spojlery. Wymaga natomiast by jadąc na Harleyu wyglądać ... "godnie" :)

2 odpowiedzi

+1 głos
odpowiedź 7 października 2020 przez adrian17 Mentor (350,440 p.)
for j in plik: #Przelatuje jedynie 500 razy zamiast 1000
    tekst = plik.readline()

Pierwsza linia wrzuca kolejne linie pliku do `j`, druga... też czyta linie pliku, do `tekst`. Czyli w każdej iteracji czytasz dwie linie, więc wykonuje się 1000/2 razy.

Zupełnie nie potrzebujesz tego readline(), bo sama pętla idzie po liniach pliku. Wystarczy:

for linia in plik:
    # uzyj linie

 

komentarz 7 października 2020 przez adrian17 Mentor (350,440 p.)

I na boku, tutaj analogicznie:

    dlugosc = len(tekst)
     
    for i in range(0, dlugosc):
        if(tekst[i] == '0'):
            zera += 1
        if(tekst[i] == '1'):
            jedynki += 1

To jest niepotrzebnie przekombinowane, jak możesz po prostu zrobić pętlę po znakach tekstu:

    for znak in tekst:
        if znak == '0':
            zera += 1
        if znak == '1':
            jedynki += 1

(no i jak widać, nawiasy są niepotrzebne)

0 głosów
odpowiedź 7 października 2020 przez Dawid Popławski Nowicjusz (160 p.)
edycja 17 grudnia 2020 przez Dawid Popławski
zera = jedynki = wynik = 0

with open("Dane_PR/liczby.txt") as file:
    for line in file:
        for char in line:
            if char == "0": zera+=1
            elif char == "1": jedynki+=1
        if zera>jedynki:
            wynik+=1
        zera = jedynki = 0
        
print(wynik)
przezdwa = przezosiem = 0
with open("Dane_PR/liczby.txt") as file:
    for line in file:
        line = int(line,2)

        if line%2 == 0:
            przezdwa += 1
        if line%8 == 0:
            przezosiem += 1
            
print(przezdwa,"|",przezosiem)
lista = []

with open("Dane_PR/liczby.txt") as file:
    for line in file:
        lista.append(int(line,2))
        
print(lista.index(max(lista))+1,"|",lista.index(min(lista))+1)

Matura 2015 maj 

Podobne pytania

0 głosów
2 odpowiedzi 904 wizyt
pytanie zadane 10 lutego 2018 w Python przez ayo1001 Obywatel (1,890 p.)
0 głosów
1 odpowiedź 671 wizyt
pytanie zadane 16 maja 2018 w PHP przez intoksynator Gaduła (3,450 p.)
0 głosów
3 odpowiedzi 364 wizyt
pytanie zadane 11 grudnia 2019 w Python przez Darven Użytkownik (860 p.)

93,165 zapytań

142,176 odpowiedzi

321,938 komentarzy

62,493 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 688p. - dia-Chann
  2. 676p. - CC PL
  3. 675p. - Łukasz Piwowar
  4. 664p. - Marcin Putra
  5. 662p. - Łukasz Eckert
  6. 649p. - Michal Drewniak
  7. 641p. - rafalszastok
  8. 641p. - rucin93
  9. 629p. - Piotr Aleksandrowicz
  10. 629p. - Adrian Wieprzkowicz
  11. 621p. - Dawid128
  12. 611p. - ksalekk
  13. 606p. - Mariusz Fornal
  14. 602p. - Michał Telesz
  15. 597p. - Hubert Chęciński
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...