Gleiche Zahlen zählen und Anzahl ausgeben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@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.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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:

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)
Beachtet die Einsen am Ende. :)
problembär

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.
Na gut, dann prüft man eben noch, ob "tocheck == 1" ist.
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.
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:

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
Eigentlich keine große Sache.
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

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]
Gibt bei mir ein korrektes Ergebnis zurück oO
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]
lunar

@JonasR: Ja und? Diese Lösung würde schon gezeigt, und nie angezweifelt.
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Auch wenn für mich sum <> len ist, was gibts denn dann noch zu diskutieren? :D
lunar

@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()".
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

lunar 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.
Okay das wusste ich nicht. Was aber mit sum wiederum nicht geht ist nach einer anderen Zahl zu suchen :D Außer man teilt das Ergebnis am ende wieder durch diese... oO
Wie habe ich das ganze mit der endlosen Iteration zu verstehen? Ich meine bei etwas endlosem kommt ja eh nie etwas zurück...
lunar

@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. :oops: Danke für den Hinweis.
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Achso hatte nur das von bords0 im Kopf :D
Antworten