neue Liste

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.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo, ich (Anfänger) suche schon seit Tagen nach einer Lösung:

die Ergebnisse der Schleife sollen nicht einzeln, sonder wieder in einer Liste stehen:

wäre sehr dankbar für einen kurzen Tipp.

Code: Alles auswählen

alle = [20,33,21,32,27,7,25,16,32,27,21,22]

for i in (alle):
    if i >0 and i<4:
        i = 1
        print(i)
    if i >3 and i<7:
        i = 2
        print(i)
    if i >6 and i<10:
        i = 3
        print(i)
    if i >9 and i<13:
        i = 4
        print(i)
    if i >12 and i<16:
        i = 5
        print(i)
    if i >15 and i<19:
        i = 6
        print(i)
    if i >18 and i<22:
        i = 7
        print(i)
    if i >21 and i<25:
        i = 8
        print(i)
    if i >24 and i<28:
        i = 9
        print(i)
    if i >27 and i<31:
        i = 10
        print(i)
    if i >30 and i<34:
        i = 11
        print(i)
    elif i>33:
        i = 12
        print(i)
print (alle)
also nicht:
>>>
7
11
7
11
9
3
9
6
11
9
7
8
>>>

sondern statt alle = [20,33,21,32,27,7,25,16,32,27,21,22] sollte stehen alle = [7,11,7,11,9,3,9,6,11,9,7,8]
Zuletzt geändert von Anonymous am Montag 9. Februar 2015, 17:02, insgesamt 2-mal geändert.
BlackJack

@haeuslermartin: Du müsstest vor der Schleife eine neue, leere Liste für das Ergebnis erstellen, und die Ergebniswerte innerhalb der Schleife dann an diese Liste anhängen. Beide Operationen gehören zu den Grundlagen die eigentlich jedes Grundlagentutorial vermitteln sollte. Zum Beispiel auch das in der Python-Dokumentation.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: am besten schreibst Du Dir eine Funktion transform_number für eine Zahl und benutzt eine List-Comprehension:
[codebox=python file=x]alle = [transform_number(i) for i in alle][/code]
BlackJack

@haeuslermartin: Ergänzend zu Sirius3: Eigentlich braucht man dafür nicht einmal eine Funktion denn das kann man auch ohne diese ganzen ``if``-Abfragen mit einem relativ einfachen Ausdruck einfach ausrechnen. Tipp, da kommt ganzzahlige Division und die `min()`-Funktion drin vor. Wenn man wie im jetzigen Code Zahlen ≤0 ausfiltern möchte bekommt die „list comprehension” (LC) noch eine Bedingung mit ``if``. Das dürfte trotzdem ein simpler Einzeiler bleiben.
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Eine Wahl:

Code: Alles auswählen

from math import ceil
alle = [20,33,21,32,27,7,25,16,32,27,21,22]
alle3 = [ceil(n/3.0) for n in alle]
print(alle3)
Atomkraftwerkaktienbesitzer
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@Ene Uran: Eine Division mit positiven ganzzahligen Zahlen entspricht immer einer Division mit Abrunden. Statt also den Umweg über ``math.ceil`` zu gehen, bietet sich ein einfaches ``n//3`` an.
Das Leben ist wie ein Tennisball.
BlackJack

@EyDu: `ceil()` ist aber auf- und nicht abrunden. Das wäre `floor()`. Ich hätte es mit Subtraktion und Addition und ausschliesslich ganzen Zahlen gelöst.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich sollte vielleicht heute mal etwas früher ins Bett gehen und morgen ausschlafen :oops:
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Da fehlt aber noch die letzte Bedingung! ;-)

Meine Lösung sähe in Clojure sähe so aus :-)

Code: Alles auswählen

(for [x [20 33 21 32 27 7 25 16 32 27 21 22]] (min (quot (+ x 2) 3) 12))
Zuletzt geändert von Hyperion am Montag 9. Februar 2015, 19:46, insgesamt 3-mal geändert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Meine in Hy:

Code: Alles auswählen

(list-comp (min 12 (// (+ x 2) 3)) [x [20 33 21 32 27 7 25 16 32 27 21 22]] (> x 0))
Mit einer zusätzlichen Bedingung.
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Also hier mal meine anfängerfreundliche Lösung:

Code: Alles auswählen

alle = [20, 33, 21, 32, 27, 7, 25, 16, 32, 27, 21, 22]
alle_neu = []
print(alle)
for i in alle:
    if i < 4:
        alle_neu.append(1)
    elif i < 7:
        alle_neu.append(2)
    elif i < 10:
        alle_neu.append(3)
    elif i < 13:
        alle_neu.append(4)
    elif i < 16:
        alle_neu.append(5)
    elif i < 19:
        alle_neu.append(6)
    elif i < 22:
        alle_neu.append(7)
    elif i < 25:
        alle_neu.append(8)
    elif i < 28:
        alle_neu.append(9)
    elif i < 31:
        alle_neu.append(10)
    elif i < 34:
        alle_neu.append(11)
    else:
        alle_neu.append(12)
    #print(alle_neu)
print(alle_neu)
Mit der for-Schleife gehst du die Elemente durch. Die if/elif Verzweigung reicht ein kleiner. Wenn der erste Wert nicht zutrifft, dann wird Bedinung zwei geprüft. Wenn nicht zutreffend dann Bedingung drei. Der Befehl "print()" gibt dir standardmäßig den Wert auf dem Bildschirm aus. Du willst aber die neuen Werte wieder in einer Liste haben. Dafür erstellen wir eine "alle_neu" Liste die leer ist. Nun werden die einzelnen Werte ermittelt und mit "append()" ans Ende der Liste angehängt. Am Schluss gibst du einmal mit "print(alle_neu)" einmal die Liste aus, die wir in der for-Schleife gefüllt haben. Jetzt hast du nicht nur die richtige Ausgabe am Bildschirm stehen, sondern auch noch ein richtiges Datenobjekt mit dem du weiter arbeiten könntest.

Falls dir unklar ist was in der Liste passiert, kannst du dir nach dem else die Liste nach jedem Durchlauf ausgeben lassen. So kannst du schön sehen wie die Liste Durchlauf für Durchlauf gefüllt wird.(Dafür musst du nur das print() auskommentieren)

Gruß
garreth
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

garreth hat geschrieben:Also hier mal meine anfängerfreundliche Lösung:
Das würde man nicht als Lösung bezeichnen, das ist nur ganz viel Copy&Paste, obwohl sich das Problem ganz leicht in wenigen Zeilen lösen lässt, auch für Anfänger. Was würdest du denn machen, wenn die Zahlen bis 1000 gehen? Oder 100000? Oder beliebig groß werden dürfen? Da hast du aber viel Schreibarbeit und eine Laufzeit, welche gegen unendlich geht ;-)
Das Leben ist wie ein Tennisball.
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

EyDu hat geschrieben:Das würde man nicht als Lösung bezeichnen, das ist nur ganz viel Copy&Paste, obwohl sich das Problem ganz leicht in wenigen Zeilen lösen lässt, auch für Anfänger. Was würdest du denn machen, wenn die Zahlen bis 1000 gehen? Oder 100000? Oder beliebig groß werden dürfen? Da hast du aber viel Schreibarbeit und eine Laufzeit, welche gegen unendlich geht ;-)
Ich entnehme dem Post des TE einfach mal, dass ihm das Prinzip einer if-elif-else Abfrage noch nicht ganz klar ist. Bestimmt ist sogut wie jede Lösung kürzer als meine, aber was nutzt mir eine komplizierte Lösung, wenn ich die Grundlagen nicht verstehe? Wie BlackJack schon sagte, hier fehlt noch grundliegendes Verständnis, welches ein Tutorial vermitteln sollte.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hier die verbesserte Clojure-Lösung mit Zusatzbedingung, die negative Zahlen verwirft:

Code: Alles auswählen

(for [x [-1 33 21 32 27 7 25 16 32 27 21 22 42] 
      :when (> x 0)] 
  (min (quot(+ x 2) 3) 12))
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo Gemeinde,

besten Dank für die Lösungsvorschläge, es scheint ja komplexer zu sein als ich dachte, wenn von Experten so verschiedene Vorschläge kommen.
Ich arbeite gerade mit dem Buch "Python 4 kids" da sind so manche Sachen (z.B. "transform") nicht enthalten, so dass ich für die "anfängerfreundliche Lösung" besonders dankbar bin.
Die Zahll der ursprünglichen Listeneinträge bleibt bei 12, im Endeffekt soll immer nur ein neuer Eintrag hinzukommen, dafür fällt der letzte aber raus.
Aber nochmals vielen Dank!
BlackJack

@haeuslermartin: So verschieden sind die Vorschläge nicht, die laufen in *Python* letztendlich alle auf sehr ähnliche „list comprehension”-Ausdrücke hinaus. Falls das nicht klar geworden sein sollte: Da sind Lösungen dabei die nicht in Python sondern in verschiedenen Lisp-Dialekten geschrieben sind. Die sehen natürlich etwas anders aus als Python, aber die Idee dahinter ist immer sehr ähnlich.

Die `tranform_number()`-Funktion die Sirius3 erwähnt hat ist natürlich nichts was in Deinem Buch vorkommt, die gibt es nämlich (noch) gar nicht, sondern die müsstest *Du* schreiben.

Wie schon gesagt wurde ist die „anfängerfreundliche Lösung” keine sinnvolle Lösung. Das würde niemand der bei Verstand ist so schreiben. Ausser Anfänger vielleicht, aber für die ist diese Lösung auch nur geeignet um zu zeigen wie man es *nicht* machen würde, und ein Anfänger sollte dringend versuchen eine vernünftige Lösung zu finden oder zu verstehen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben: Wie schon gesagt wurde ist die „anfängerfreundliche Lösung” keine sinnvolle Lösung. Das würde niemand der bei Verstand ist so schreiben. Ausser Anfänger vielleicht, aber für die ist diese Lösung auch nur geeignet um zu zeigen wie man es *nicht* machen würde, und ein Anfänger sollte dringend versuchen eine vernünftige Lösung zu finden oder zu verstehen.
+1 :!:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Code: Alles auswählen

from math import ceil
alle = [20, 33, 21, 32, 27, 7, 25, 16, 32, 27, 21, 22]
alle = list(map(lambda x: ceil(x/3), alle))
print(alle)
ohne import:

Code: Alles auswählen

def transform_number(i):
    result = i / 3
    if result < i//3+0.5 and i % 3 != 0:
        result += 1
    return round(result)

if __name__ == '__main__':
    alle = [20, 33, 21, 32, 27, 7, 25, 16, 32, 27, 21, 22]
    alle = list(map(lambda x: transform_number(x), alle))
    print(alle)
So und jetzt nochmals, ich habe nie behauptet, dass die "anfängerfreundliche Lösung" eine Lösung für den produktiven Einsatz ist. Es ist ein Beispiel, an dem man die Funktion einer if-elif-else Abfrage gut nachvollziehen können sollte. Nicht mehr, nicht weniger.
Jeder muss mit seinen Mitteln arbeiten und Anfänger haben nunmal die Grundsteine nicht um sämtliche hier gezeigte Lösungen zu verstehen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

garreth hat geschrieben:So und jetzt nochmals, ich habe nie behauptet, dass die "anfängerfreundliche Lösung" eine Lösung für den produktiven Einsatz ist. Es ist ein Beispiel, an dem man die Funktion einer if-elif-else Abfrage gut nachvollziehen können sollte. Nicht mehr, nicht weniger.
Das ist es ja gerade nicht. Der Code zeigt nämlich nur gut, wann genau man ein ein if/elif/else *nicht* einsetzen sollte. Der TE hat ja wohl eher weniger Probleme mit bedingten Anweisungen an sich, sondern wann man diese einsetzt und wann Code sinnvoll in (in Schleifen) zusammengefasst werden kann. Und wenn du das Konstrukt erklären möchtest, dann braucht es dazu keine 10 elif-Zweige. Zwei Stück in einem sinnvollen Szenario hätten gereicht.
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

garreth hat geschrieben:Also hier mal meine anfängerfreundliche Lösung:
Das zeigt sehr schön, wie genau Programmierung *nicht* funktioniert. Auch nicht für einen Anfänger. Aber das wurde ja bereits mehrfach auch von anderen kritisiert.
Antworten