• 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

VPS Starter Arubacloud
0 głosów
211 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 (90,690 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 (155,460 p.)

Hmm..

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

 

komentarz 8 października 2020 przez Benek Szeryf (90,690 p.)
Menadżer kontekstu by się jednak przydał.
komentarz 8 października 2020 przez mokrowski Mędrzec (155,460 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 (90,690 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 (155,460 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 Ekspert (344,100 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 Ekspert (344,100 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 544 wizyt
pytanie zadane 10 lutego 2018 w Python przez ayo1001 Obywatel (1,890 p.)
0 głosów
1 odpowiedź 439 wizyt
pytanie zadane 16 maja 2018 w PHP przez intoksynator Gaduła (3,450 p.)
0 głosów
3 odpowiedzi 315 wizyt
pytanie zadane 11 grudnia 2019 w Python przez Darven Użytkownik (860 p.)

92,454 zapytań

141,262 odpowiedzi

319,099 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...