Stelle von der Maximalwert aus einer Liste.Achtung ANFÄNGER!

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.
Antworten
Disaster
User
Beiträge: 8
Registriert: Freitag 27. Januar 2012, 22:11

Hallo Leute, Ich will mich zuerst bei euch Vorstellen weil ich Neu im Forum bin.
Mein Name ist Sercan und ich mache zurzeit ein Schulische Ausbildung für Informatik...
Bin seit 7 Jahren in Deutschland und beherrsche die Deutsche Sprache noch nicht so gut (also
nicht wundern falls es mal vorkommt , dass ich Rechtschreibfehler habe oder mich nicht genug
ausdrucken kann). Dann komme ich schnell mal zu mein Problem. Ich habe c.a. 2 Stunden im Internet gesucht
aber leider ohne Erfolg :( und da habe ich mir gedacht :idea: dass ich eventuell von euch Hilfe holen kann :roll: .

Problem: Ich suche ein Befehl was mir die Stelle von dem Maximalwert aus der Liste gibt. Ich weiß zwar
dass ich mit max(listenname) den Maximalwert finde aber ich muss für den Problem die Stelle , der Maximalwert finden (Es handelt sich um eine Liste mit Integerzahlen).

Ich bedanke mich für jede Antwort schonmal im Vorraus.

Eine Dumme lösung habe ich aber ich dachte vllt. gibt es extra ein Befehl dafuer.
Die dumme Lösung:

Code: Alles auswählen

liste = [823, 8123, 428, 581, 102]

for l in range(len(liste)):
    for i in range(len(liste)):
        if liste[i] == max(liste):
            print "Groesste Zahl : " liste[i]
            del liste[i]
MfG Disaster.
BlackJack

@Disaster: Das ist keine Lösung. Da wird nicht mal ansatzweise der Index des Maximums ermittelt. Das dürfte nicht einmal fehlerfrei durchlaufen sondern in einem `IndexError` enden. Es sieht also so aus als wenn Du *irgend etwas* hingeschrieben hast um ein wenig Initiative vor zu täuschen, das nicht einmal ausprobiert hast, und jetzt gerne eine Lösung von anderen für Deine Hausaufgabe haben möchtest.

Es reicht nicht zwei Stunden im Internet zu suchen — Du musst ein Tutorial durcharbeiten um die Programmiersprache zu lernen und das Wissen daraus dann anwenden. Das Tutorial in der Python-Dokumentation wäre ein Einstieg. Ein zusätzlicher Blick in die Dokumentation was Listen an Methoden bieten, könnte auch hilfreich sein.
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

Hallo Sercan,
dein Deutsch ist doch perfekt.
Und zu deiner Frage:
das würde ich so lösen:

Code: Alles auswählen

def max_index(liste):
        return (max(liste),liste.index(max(liste)))
Dabei beschreibt max(liste) den Maximalwert und liste.index(max(liste)) den Index dieses Wertes.

P.S Außerdem bitte ich um Entschuldigung, dass ich mich wie der letzte Hans benommen habe. Nehmt ihr meine Entschuldigung an?
Disaster
User
Beiträge: 8
Registriert: Freitag 27. Januar 2012, 22:11

@BlackJack:

Es war nicht meine Absicht von euch meine Hausaufgaben erledigen zu lassen. Unsere Aufgabe war:
Es sind 3 .txt Dateien gegeben wo drinne 5000 Zufallszahlen von Würfen drinne stehen. EinerWurf.txt, ZweierWurf.txt und DreierWurf.txt. Am anfang des Programms kommt eine Abfrage wo der User auszuwählen hat ob er mit 1 , 2 oder 3 Würfel würfeln möchte, je nach Auswahl wird in der TXT datei nach der Häufigkeit einzelne Zahlen durchgeguckt und in eine Liste gespeichert. Am Ende des Programmes, wird eine Liste ausgegeben , welches Anzeigt wie Oft eine Zahl vorgekommen ist (Häufigkeit und Prozent). Bevor dies geschieht wird der User gefragt, wie er die Liste ausgegeben bekommen will. Die 2 Varianten was der User auswählen kann:
Die erste Variante ist die Liste von oben nach Unten nach Würfelzahlen 1...6, 1...12 oder 1...18 (von der kleinste Zahl angefangen), auszugeben.
Problem: Die 2. Variante ist die Liste nach Häufigkeit zu sortieren , so dass die Zahl mit dem häufigsten vorkommen ganz oben steht. Ich wollte dieses Befehl einfach aus dem Grunde , damit ich die max(zahl) in die Liste einblende und ich dann auch angeben kann um Welche Zahl es sich handelt(Würfelzahl).

Ich wollte nicht das du mir meine Hausaufgabe löst , sondern nur eine Hilfe da ich mit dem Sortieren nach Häufigkeit nicht weitergekommen bin.
BlackJack

@Disaster: Zum sortieren ist `max()` nicht wirklich geeignet, denn damit sortiert man nicht, sondern ermittelt nur das Maximum. Zum Sortieren von Listen gibt es eine Methode auf `list`-Objekten wenn man eine Liste „in place” sortieren möchte, oder eine Funktion die aus einem beliebigen iterierbaren Objekt — also zum Beispiel Listen — eine sortierte Liste erstellt.

Einfach die Liste mit Werten sortieren geht nicht, weil Du ja den Index zu den Werten auch brauchst, also musst Du eine sortierte Liste erstellen, die Paare von Häufigkeit und Index enthält.

@Newcomer: Ist vom Algorithmus her ein wenig ineffizient, weil die Liste so zweimal durchlaufen wird — einmal um das Maximum zu finden, und dann noch einmal um den Index von dem Maximum zu finden. Das könnte man auch in einem Durchgang erledigen wenn man sich beim Maximum suchen auch gleich den Index merkt, der zu jedem Wert gehört:

Code: Alles auswählen

from operator import itemgetter


def main():
    values = [1, 2, 42, 3]
    index_of_maximum = max(enumerate(values), key=itemgetter(1))[0]
    print index_of_maximum


if __name__ == '__main__':
    main()
Disaster
User
Beiträge: 8
Registriert: Freitag 27. Januar 2012, 22:11

Danke euch ich habe das Problem jetzt gelöst. Danke nochmal an BlackJack , dass du mir doch weitergeholfen hast :)
Kann geschlossen werden
BlackJack

Mal spasseshalber eine Lösung in Vala:

Code: Alles auswählen

using Gee;

const string[] name_prefixes = {"Einer", "Zweier", "Dreier"};
const string[] sort_criteria = {"Wert", "Häufigkeit"};

class HistogramEntry : Object, Comparable<HistogramEntry>
{
    private weak Histogram histogram;
    public uint value;
    public uint frequency;
    
    internal HistogramEntry(Histogram histogram, uint value, uint frequency=0)
    {
        this.histogram = histogram;
        this.value = value;
        this.frequency = frequency;
    }
    
    public int compare_to(HistogramEntry other)
    {
        return (int) other.frequency - (int) this.frequency;
    }
    
    public string to_string(string format="%3u, %u, %.2f%%")
    {
        return format.printf(
            this.value,
            this.frequency,
            100.0 / this.histogram.total * this.frequency
        );
    }
}

class Histogram : Object
{
    private ArrayList<HistogramEntry> data;
    public uint total = 0;
    
    public Histogram(uint count)
    {
        this.data = new ArrayList<HistogramEntry>();
        for (var i = 1; i <= count; ++i) {
            this.data.add(new HistogramEntry(this, i));
        }
    }
    
    public Histogram.load(string filename, uint count)
    {
        this(count);
        var file = FileStream.open(filename, "r");
        string line;
        while ((line = file.read_line()) != null) {
            this.count(int.parse(line));
        }
    }
    
    public void count(uint value)
    {
        this.data[(int) value - 1].frequency++;
        this.total++;
    }
    
    public void sort()
    {
        this.data.sort();
    }
    
    public string to_string()
    {
        string[] lines = {"Val, Freq, %"};
        foreach (var entry in this.data) {
            lines += entry.to_string();
        }
        return string.joinv("\n", lines);
    }
}

int menu(string title, string[] choices)
{
    int result;
    
    while (true) {
        stdout.printf("%s\n\n", title);
        for (var i = 0; i < choices.length; ++i) {
            stdout.printf("%2d. %s\n", i + 1, choices[i]);
        }
        stdout.putc('?');
        var line = stdin.read_line();
        result = int.parse(line);
        if (1 <= result && result <= choices.length) {
            return result - 1;
        }
        stdout.printf("'%s' ist keine gültige Eingabe!\n\n", line);
    }
}

void main()
{
    var choice = menu("Welche Datei?", name_prefixes);
    var histogram = new Histogram.load(
        name_prefixes[choice] + "Wurf.txt", (choice + 1) * 6
    );
    
    choice = menu("Sortieren nach?", sort_criteria);
    if (choice == 1) histogram.sort();
    stdout.printf("%s\n", histogram.to_string());
}
deets

@BlackJack

:shock: Du hast zuviel Zeit..
BlackJack

@deets: Nee, wenn ich zu viel Zeit hätte, dann hätte ich da noch ordentliche Fehlerbehandlung eingebaut. ;-)

Ich wollte passend zur Diskussion über C++ im Offtopic-Bereich mal wieder mit einer Alternative dazu experimentieren.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

BlackJack hat geschrieben:

Code: Alles auswählen

    index_of_maximum = max(enumerate(values), key=itemgetter(1))[0]
War jetzt - bevor ich mir deine Lösung angesehen hatte - zu folgendem gekommen:

Code: Alles auswählen

max(enumerate(l), key=lambda x:x[1])[0]
Habe ich was übersehen, oder ist das äquivalent?
BlackJack

@nezzcarth: Abgesehen vom letzten ``[0]`` um den Index aus dem Tupel zu holen, ist das äquivalent.

Edit: Entweder war ich zu verplant, oder das ``[0]`` ist da nachträglich nich aufgetaucht. Ich sollte wieder ins Bett gehen…
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Das ist in etwa dasselbe, nur dass es IMHO besser ist mit `itemgetter` zu arbeiten, da es halt schon eine Funktion für genau diesen Zweck ist.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

Alles klar. Deswegen hab ich nachgefragt ;)
Vielen Dank, euch beiden.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

BlackJack hat geschrieben:@Newcomer: Ist vom Algorithmus her ein wenig ineffizient, weil die Liste so zweimal durchlaufen wird — einmal um das Maximum zu finden, und dann noch einmal um den Index von dem Maximum zu finden. Das könnte man auch in einem Durchgang erledigen wenn man sich beim Maximum suchen auch gleich den Index merkt, der zu jedem Wert gehört:

Code: Alles auswählen

from operator import itemgetter


def main():
    values = [1, 2, 42, 3]
    index_of_maximum = max(enumerate(values), key=itemgetter(1))[0]
    print index_of_maximum


if __name__ == '__main__':
    main()
Warum sollte das effizienter sein? Von der Komplexität her ist es ja ohnehin gleich. Und das Durchlaufen einer Liste geht ja in reinem C-Code, auch der Vergleich (von int-Objekten) ist sicher sehr schnell - ich würde Tippen, dass das schneller ist als das Bauen von Tupeln und Aufruf des itemgetters (Funktionsaufrufe sind ja bekanntlich "teuer" in Python), der dann den interessanten Wert wieder herauspfriemelt.

Code: Alles auswählen

>>> setup="""values=list(range(100))
... from operator import itemgetter"""
>>> stmt="""max(enumerate(values), key=itemgetter(1))[0]"""
>>> stmt2="""values.index(max(values))"""
>>> timeit.timeit(stmt=stmt, setup=setup)
22.52865992744887
>>> timeit.timeit(stmt=stmt2, setup=setup)
8.706310997626815
Wenn das Maximum nicht gerade der letzte Wert ist, wird der Unterschied noch größer...
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Also mal mit einem gescheiten Werkzeug gemessen (time):
$ time python enum.py

real 0m0.039s
user 0m0.032s
sys 0m0.004s
$ time python indexmax.py

real 0m0.039s
user 0m0.028s
sys 0m0.008s
indexmax.py:

Code: Alles auswählen

VALUES = range(100)

VALUES.index(max(VALUES))
enum.py:

Code: Alles auswählen

from operator import itemgetter

VALUES = range(100)

max(enumerate(VALUES), key=itemgetter(1))[0]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nomnom hat geschrieben:Also mal mit einem gescheiten Werkzeug gemessen (time):
Als ein gescheites Werkzeug wäre hier eher das `timeit`-Modul!

Code: Alles auswählen

nelson@destiny ~/src/Python/snippets % python -m timeit -s "VALUES = range(100)" -- "VALUES.index(max(VALUES))"


100000 loops, best of 3: 10.5 usec per loop
nelson@destiny ~/src/Python/snippets % python -m timeit -s "from operator import itemgetter; VALUES = range(100)" -- "max(enumerate(VALUES), key=itemgetter(1))[0]"
10000 loops, best of 3: 38.7 usec per loop
Ich gebe zu, das überrascht mich jetzt...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Hyperion hat geschrieben:
nomnom hat geschrieben:Also mal mit einem gescheiten Werkzeug gemessen (time):
Als ein gescheites Werkzeug wäre hier eher das `timeit`-Modul!
Hm, `timeit` rühre ich nicht mehr an, weil ich nicht verstehe warum das immer so absurde Zeiten misst.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nomnom hat geschrieben:Hm, `timeit` rühre ich nicht mehr an, weil ich nicht verstehe warum das immer so absurde Zeiten misst.
Und stattdessen ist Dir das "Einmalausführen" inkl. Overhead lieber und verlässlicher? :twisted:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Hyperion hat geschrieben:
nomnom hat geschrieben:Hm, `timeit` rühre ich nicht mehr an, weil ich nicht verstehe warum das immer so absurde Zeiten misst.
Und stattdessen ist Dir das "Einmalausführen" inkl. Overhead lieber und verlässlicher? :twisted:
Ich habe wie du `time` dreimal je Skript ausgeführt und die Werte rausgesucht. :P Und der Overhead ist mir eigentlich egal, der sollte ja eigentlich immer genauso lange brauchen.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Hyperion hat geschrieben:Ich gebe zu, das überrascht mich jetzt...
Mich nicht.

Code: Alles auswählen

def search_1():
    return VALUES.index(max(VALUES))

def search_2():
    return max(enumerate(VALUES), key=itemgetter(1))[0]

pprint(dis.dis(search_1))
pprint(dis.dis(search_2))

Code: Alles auswählen

14            0 LOAD_GLOBAL              0 (VALUES)
              3 LOAD_ATTR                1 (index)
              6 LOAD_GLOBAL              2 (max)
              9 LOAD_GLOBAL              0 (VALUES)
             12 CALL_FUNCTION            1
             15 CALL_FUNCTION            1
             18 RETURN_VALUE        

17            0 LOAD_GLOBAL              0 (max)
              3 LOAD_GLOBAL              1 (enumerate)
              6 LOAD_GLOBAL              2 (VALUES)
              9 CALL_FUNCTION            1
             12 LOAD_CONST               1 ('key')
             15 LOAD_GLOBAL              3 (itemgetter)
             18 LOAD_CONST               2 (1)
             21 CALL_FUNCTION            1
             24 CALL_FUNCTION          257
             27 LOAD_CONST               3 (0)
             30 BINARY_SUBSCR       
             31 RETURN_VALUE
Antworten