Gleiche Zahlen zählen und Anzahl ausgeben
@problembär: Das löst aber nicht die Aufgabe. Es sollen nicht alle Läufe von gleichen Zahlen ermittelt werden, sondern nur die von den 1en. Selbst wenn Du damit alle Läufe zählen möchtest, hat auch diese Lösung das Problem, dass der letzte Wert des Ergebnisses fehlt. Die Ausgabe endet mit einer 1, aber sie müsste ja wegen den zwei letzten 0en mit einer 2 enden.
Das meinte ich eigentlich auch mit "(...) beachtet noch nicht die Einwürfe von BlackJack".
Es hat sich also gezeigt, dass mein Ablauf ungenau definiert war. Als Mensch würde ich ein Ergebnis unter Umständen auch dann aufschreiben, wenn keine Zahlen mehr übrig sind. Damit ich es aufschreibe, muss das Ergebnis grundsätzlich größer als Null sein.
Um in Python herauszufinden, ob noch weitere Iterationsschritte nötig sind, fallen mir diverse Möglichkeiten ein:
1. Elemente mittels `.pop()` abfragen und möglichen `IndexError` behandeln. `.pop()` ist allerdings auf Listen beschränkt.
2a. Weiteren Iterator einführen, der quasi einen Schritt voraus ist und mittels `next()` prüft.
2b. Lediglich *einen* Iterator benutzen, aber `for` durch `while` ersetzen und auch hier mit `next()` arbeiten.
3. Die Schleife durchlaufen und am Ende prüfen, ob Zählstand > 0 ist. Dann genau so verfahren, wie nach einem "Zahlen-Switch". Bedeutet sozusagen Copy&Paste im Kleinformat oder die Einführung einer Hilfsfunktion.
4. Die Länge der Zahlenliste merken und in jedem Schleifendurchlauf dekrementieren.
Ich habe mich dann für die letzte Möglichkeit entschieden und die Funktion gleich auch etwas generischer gestaltet:
Beachtet die Einsen am Ende.
Es hat sich also gezeigt, dass mein Ablauf ungenau definiert war. Als Mensch würde ich ein Ergebnis unter Umständen auch dann aufschreiben, wenn keine Zahlen mehr übrig sind. Damit ich es aufschreibe, muss das Ergebnis grundsätzlich größer als Null sein.
Um in Python herauszufinden, ob noch weitere Iterationsschritte nötig sind, fallen mir diverse Möglichkeiten ein:
1. Elemente mittels `.pop()` abfragen und möglichen `IndexError` behandeln. `.pop()` ist allerdings auf Listen beschränkt.
2a. Weiteren Iterator einführen, der quasi einen Schritt voraus ist und mittels `next()` prüft.
2b. Lediglich *einen* Iterator benutzen, aber `for` durch `while` ersetzen und auch hier mit `next()` arbeiten.
3. Die Schleife durchlaufen und am Ende prüfen, ob Zählstand > 0 ist. Dann genau so verfahren, wie nach einem "Zahlen-Switch". Bedeutet sozusagen Copy&Paste im Kleinformat oder die Einführung einer Hilfsfunktion.
4. Die Länge der Zahlenliste merken und in jedem Schleifendurchlauf dekrementieren.
Ich habe mich dann für die letzte Möglichkeit entschieden und die Funktion gleich auch etwas generischer gestaltet:
Code: Alles auswählen
def count_occurrences(iterable, keyname):
remaining = len(iterable)
results = []
counter = 0
for elem in iterable:
remaining -= 1
if elem == keyname:
counter += 1
if counter and (elem != keyname or not remaining):
results.append(counter)
counter = 0
return results
numbers = [0,0,0,0,1,1,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,1,1,1]
print count_occurrences(numbers, 1)
Na gut, dann prüft man eben noch, ob "tocheck == 1" ist.BlackJack hat geschrieben:@problembär: Das löst aber nicht die Aufgabe. Es sollen nicht alle Läufe von gleichen Zahlen ermittelt werden, sondern nur die von den 1en.
Stimmt, das soll natürlich nicht sein. Das Problem ist, daß der letzte Wechsel nicht mehr in der Schleife berücksichtigt wird, weil kein weiterer Wechsel mehr folgt (und innerhalb der Schleife nur auf Wechsel der Listenelemente geprüft wird). Dann fügt man eben nach der Schleife noch den letzten Stand von "count" der Ergebnisliste an. Also:BlackJack hat geschrieben:Selbst wenn Du damit alle Läufe zählen möchtest, hat auch diese Lösung das Problem, dass der letzte Wert des Ergebnisses fehlt. Die Ausgabe endet mit einer 1, aber sie müsste ja wegen den zwei letzten 0en mit einer 2 enden.
Code: Alles auswählen
#!/usr/bin/env python
# coding: iso-8859-1
numbers = (0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
counts = []
startvalue = -1
tocheck = startvalue
count = 0
for i in numbers:
if i == tocheck:
count +=1
else:
if tocheck != startvalue and tocheck == 1:
counts.append(count)
tocheck = i
count = 1
if tocheck == 1:
counts.append(count)
for i in counts:
print i
Code: Alles auswählen
import itertools
numbers = [0,0,0,0,1,1,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1]
groups = (list(grp) for key, grp in itertools.groupby(numbers) if key == 1)
print [len(list_len) for list_len in groups]
Oder habe ich mal wieder was überlesen?
btw Ergebniss = [2, 4, 7, 1, 3, 1]
€ bzw
Code: Alles auswählen
import itertools
numbers = [0,0,0,0,1,1,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1]
print [len(list(grp)) for key, grp in itertools.groupby(numbers) if key == 1]
@JonasR: Mit "sum()" funktioniert die Lösung auch mit endlosen Iteratoren, und ist zudem speicherschonender, weil keine vollständige Liste aller Werte der aktuellen Zählergruppe nötig ist.
Diskutiert wird gerade über die Lösungen ohne "groupby()".
Diskutiert wird gerade über die Lösungen ohne "groupby()".
Okay das wusste ich nicht. Was aber mit sum wiederum nicht geht ist nach einer anderen Zahl zu suchen Außer man teilt das Ergebnis am ende wieder durch diese... oOlunar hat geschrieben:@JonasR: Mit "sum()" funktioniert die Lösung auch mit endlosen Iteratoren, und ist zudem speicherschonender, weil keine vollständige Liste aller Werte der aktuellen Zählergruppe nötig ist.
Wie habe ich das ganze mit der endlosen Iteration zu verstehen? Ich meine bei etwas endlosem kommt ja eh nie etwas zurück...
@JonasR: Bei "sum()" muss man eben explizit 1 aufaddieren.
Meine Behauptung mit der endlosen Iteration war natürlich Blödsinn, "sum()" würde in diesem Fall ja auch nicht terminieren. Danke für den Hinweis.
Meine Behauptung mit der endlosen Iteration war natürlich Blödsinn, "sum()" würde in diesem Fall ja auch nicht terminieren. Danke für den Hinweis.