• 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

Cloud VPS
0 głosów
380 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 (93,190 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 (158,980 p.)

Hmm..

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

 

komentarz 8 października 2020 przez Benek Szeryf (93,190 p.)
Menadżer kontekstu by się jednak przydał.
komentarz 8 października 2020 przez mokrowski Mędrzec (158,980 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 (93,190 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 (158,980 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 (354,720 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 (354,720 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 1,154 wizyt
pytanie zadane 10 lutego 2018 w Python przez ayo1001 Obywatel (1,890 p.)
0 głosów
1 odpowiedź 858 wizyt
pytanie zadane 16 maja 2018 w PHP przez intoksynator Gaduła (3,450 p.)
0 głosów
3 odpowiedzi 409 wizyt
pytanie zadane 11 grudnia 2019 w Python przez Darven Użytkownik (860 p.)

93,487 zapytań

142,423 odpowiedzi

322,773 komentarzy

62,908 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

Kursy INF.02 i INF.03
...