Die untenstehende Funktion soll die Länge einer Liste berechnen. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee? def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 listenlaenge(liste[1:], zaehler) # >>> a = listenlaenge([2, 5, 6, 1]) # zaehler: 4 # >>> a # >>> print(a) # None
On 2024-07-02 18:56, Andreas Röhler <andreas.roehler@online.de> wrote:
Die untenstehende Funktion soll die Länge einer Liste berechnen. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 listenlaenge(liste[1:], zaehler)
Hier fehlt das return. hp
Mit einem zweiten ‘return’ im else-Zweig funktioniert es. Verstehe das allerdings nicht: ‘else’ sollte nur die Funktion mit dem neuen Zähler aufrufen, selbst aber nichts zurückgeben. def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 return listenlaenge(liste[1:], zaehler) a = listenlaenge([2, 5, 6, 1]) print("a: {}".format(a)) # >>> zaehler: 4 # a: 4 Am 02.07.24 um 23:02 schrieb Peter J. Holzer:
On 2024-07-02 18:56, Andreas Röhler <andreas.roehler@online.de> wrote:
Die untenstehende Funktion soll die Länge einer Liste berechnen. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 listenlaenge(liste[1:], zaehler) Hier fehlt das return.
hp _______________________________________________ python-de Mailingliste -- python-de@python.org Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an python-de-leave@python.org https://mail.python.org/mailman3/lists/python-de.python.org/ Mitgliedsadresse: andreas.roehler@online.de
On 2024-07-03 14:28, Andreas Röhler <andreas.roehler@online.de> wrote:
Mit einem zweiten ‘return’ im else-Zweig funktioniert es.
Verstehe das allerdings nicht: ‘else’ sollte nur die Funktion mit dem neuen Zähler aufrufen, selbst aber nichts zurückgeben.
Doch. Natürlich soll das was zurückgeben. Wie sollte sonst das Ergebnis zum Aufrufer kommen?
Am 03.07.24 um 16:28 schrieb Andreas Röhler:
Verstehe das allerdings nicht: ‘else’ sollte nur die Funktion mit dem neuen Zähler aufrufen, selbst aber nichts zurückgeben.
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 return listenlaenge(liste[1:], zaehler)
So etwa? def listenlaenge (liste, zaehler=0): while True: if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 return listenlaenge(liste[1:], zaehler) -- <http://www.hermann-riemann.de>
On 2024-07-03 19:14, Hermann Riemann <nospam.ng@hermann-riemann.de> wrote:
Am 03.07.24 um 16:28 schrieb Andreas Röhler:
Verstehe das allerdings nicht: ‘else’ sollte nur die Funktion mit dem neuen Zähler aufrufen, selbst aber nichts zurückgeben.
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 return listenlaenge(liste[1:], zaehler)
So etwa?
def listenlaenge (liste, zaehler=0): while True: if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 return listenlaenge(liste[1:], zaehler)
:-O
Andreas Röhler in de.comp.lang.python:
Die untenstehende Funktion soll die Länge einer Liste berechnen.
len(liste)
Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
Das "return" darf wohl nicht in der zweiten Ebene innerhalb der Funktion stehen, sondern muß in der ersten erscheinen. <https://docs.python.org/3/reference/simple_stmts.html#the-return-statement> | user15@o15:/tmp$ cat ll.py | #!/usr/bin/python3 | def listenlaenge(li): | z=0 | while li!=[]: | z+=1 | li=li[1:] | return z | | g=[53,535,2,3,7,64,356,3452] | | a=listenlaenge(g) | print(a) | user15@o15:/tmp$ ./ll.py | 8 | user15@o15:/tmp$ Marcel (Lines: 39) -- │ ╭─╮ ╭─╮ ╭────╮ ..63..╭───────────────╮ ╰─╮ │ ╰──╯ ╰────╮ ╭─╯ │ ..68.. ╰──╮ ╭─────────╯ ╭─ ╰───╯ ╭────────╯ │ ╭───╯ ╭─╮ ╭──────╯ ╰─╮ ╭─╮ ╭────────╮ │ ...4..╰──────────╯ ╰──────────╯ ╰─╯ ╰─╯ ╰──╯ ╰───╯
On 2024-07-02 22:09, Marcel Logen <333200007110-0201@ybtra.de> wrote:
Andreas Röhler in de.comp.lang.python:
Die untenstehende Funktion soll die Länge einer Liste berechnen.
len(liste)
Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
Das "return" darf wohl nicht in der zweiten Ebene innerhalb der Funktion stehen, sondern muß in der ersten erscheinen.
Nein, ein return darf an jeder Stelle in einer Funktion stehen. Aber um einen Effekt zu haben, muss es erreicht werden. Und in Andreas' Code gibt es eben einen Pfad, der an keinem return vorbeikommt. Erreicht eine Funktion ihr Ende, ohne return, dann gibt sie None zurück. hp
Am 03.07.24 um 00:09 schrieb Marcel Logen:
Andreas Röhler in de.comp.lang.python:
Die untenstehende Funktion soll die Länge einer Liste berechnen. len(liste) Ja, ist hier nur eine Übung. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee? Das "return" darf wohl nicht in der zweiten Ebene innerhalb der Funktion stehen, sondern muß in der ersten erscheinen.
# Die Ebene kann nicht der Grund sein. Untenstehendes Programm gibt den Wert # von zweiter Ebene zurück und bindet diesen auch an "a". def add_result(a, b) -> int: result = a + b if result == 4: return result else: print("Nicht gleich 4") a = add_result(1, 3) print("a: {}".format(a)) b = add_result(1, 4) print("b: {}".format(b)) # >>> a: 4 # Nicht gleich 4 # b: None
<https://docs.python.org/3/reference/simple_stmts.html#the-return-statement>
|return| <https://docs.python.org/3/reference/simple_stmts.html#return> may only occur syntactically nested in a function definition Hier sehe ich keinen Grund für den Fehler.
| user15@o15:/tmp$ cat ll.py | #!/usr/bin/python3 | def listenlaenge(li): | z=0 | while li!=[]: | z+=1 | li=li[1:] | return z | | g=[53,535,2,3,7,64,356,3452] | | a=listenlaenge(g) | print(a)
| user15@o15:/tmp$ ./ll.py | 8
Das funktioniert Aufgabe/Test war allerdings eine rekursive Schreibweise. Gruß und Dank an alle, Andreas
| user15@o15:/tmp$
Marcel (Lines: 39)
Andreas Röhler <andreas.roehler@online.de> writes:
Die untenstehende Funktion soll die Länge einer Liste berechnen. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 listenlaenge(liste[1:], zaehler)
Im "else" Teil gibt du ja keinen Funktionswert zurück. Wenn das rekrsiv sein soll, dann vielleicht so: def listenlaenge(liste): if liste == []: return 0 else: return listenlaenge(liste[1:]) + 1 Zur Dokumentation schreibt man auch def listenlaenge(liste) -> int: damit klar ist, dass hier ein Rückgabewert kommt (kommen sollte). Oder du verwendest die eingebaute Funktion len(liste) -- Stephan
Am 02.07.24 um 20:56 schrieb Andreas Röhler:
print("zaehler: {}".format(zaehler))
Immer wieder sehe ich diese unnötigen und ineffizienten String-Formatierungen bei "print". print("zaehler:", zaehler) tut genau das gleiche. -- Regards Hartmut Goebel | Hartmut Goebel | h.goebel@crazy-compilers.com | | www.crazy-compilers.com | compilers which you thought are impossible |
On 2024-07-03 09:14, Hartmut Goebel <h.goebel@crazy-compilers.com> wrote:
Am 02.07.24 um 20:56 schrieb Andreas Röhler:
print("zaehler: {}".format(zaehler))
Immer wieder sehe ich diese unnötigen und ineffizienten String-Formatierungen bei "print".
Unnötig kompliziert und schwer zu lesen? Ja, zumindest in diesem Fall (es gibt durchaus Fälle, wo ein format übersichtlicher ist). Ineffizient? Bitte im Zahlen. Ich bezweifle, dass das einen wesentlichen Unterschied macht. Formatiert muss die Zahl ohnehin werden, und ob das explizit vor dem Aufruf von print() passiert oder implizit durch print(), macht fast sicher keinen Unterschied. [kurzer Test] Tatsächlich ist diese Variante:
print("zaehler:", zaehler)
die langsamste. Am schnellsten sind das gute alte %: print("zaehler: %s" % zaehler) und die neumodischen f-Strings: print(f"zaehler: {zaehler}") (ziemlich gleichauf). str.format() ist in der Mitte. Aber die Unterschiede sind so gering, dass ich mir keine Gedanken darüber machen würde, außer das Programm verbringt 90% seiner Zeit in print-Statements. Verwendet einfach das, was Euch am besten lesbar erscheint. hp
Am 03.07.24 um 13:43 schrieb Peter J. Holzer:
Ineffizient?
Ja, denn wenn der String erst als ganzes formatiert wird, muss erstmal der Speicher für den ganzen String alloziert werden, ehe der String ausgegeben werden kann. Das mag von Pythons Speicher-Management abgefangen werden und auf aktuellen Rechnern nicht messbar sein - trotzdem wird mehr Rechenzeit und Speicher benötigt :-) Siehe auch https://de.wikipedia.org/wiki/Wirthsches_Gesetz -- Regards Hartmut Goebel | Hartmut Goebel |h.goebel@crazy-compilers.com | |www.crazy-compilers.com | compilers which you thought are impossible |
On 2024-07-03 12:41, Hartmut Goebel <h.goebel@crazy-compilers.com> wrote:
Am 03.07.24 um 13:43 schrieb Peter J. Holzer:
Ineffizient?
Ja, denn wenn der String erst als ganzes formatiert wird, muss erstmal der Speicher für den ganzen String alloziert werden, ehe der String ausgegeben werden kann.
Das mag von Pythons Speicher-Management abgefangen werden und auf aktuellen Rechnern nicht messbar sein - trotzdem wird mehr Rechenzeit und Speicher benötigt :-)
Wie gesagt, meine Tests ergeben, dass print("x", x) langsamer ist. Was auch immer print() da im Hintergrund macht, es braucht *mehr* Rechenzeit und möglicherweise auch mehr Speicher. Kontrafaktisch die ineffizientere Lösung mit der Begründung einer Effizienzsteigerung zu vertreten, hat zwar in der IT Tradition, aber es ist keine gute Tradition. Ich sehe Deinen Smiley, aber ich reite trotzdem darauf herum: Ich erlebe es immer wieder, dass Leute Programme auf Grund einer vagen Idee "optimieren", ohne vorher zu messen, ob das tatsächlich ein Bottleneck ist. Am Ende ist das Programm dann nicht schneller (vielleicht sogar langsamer), schlechter lesbar, und sie haben einen Haufen Arbeitszeit verschwendet. Wenn man wirklich optimieren möchte (und nicht nur Zeit totschlagen), dann muss man dort anfangen, wo am meisten Zeit aufgewendet wird. Daraus ergeben sich dann meistens Änderungen im Algorithmus. Oder gar - shockingly - die Erkenntnis, dass das bei Python der Interpreter selbst ist. Pypy statt CPython kann einen ordentlichen Performance-Boost bringen. Teile mit Cython zu kompilieren oder gar in einer anderen Programmiersprache zu implementieren noch mehr. An den Details einer Stringformatierung herumzudoktern ziemlich sicher nicht. hp
Am 03.07.24 um 11:14 schrieb Hartmut Goebel:
Am 02.07.24 um 20:56 schrieb Andreas Röhler:
print("zaehler: {}".format(zaehler))
Immer wieder sehe ich diese unnötigen und ineffizienten String-Formatierungen bei "print".
print("zaehler:", zaehler)
tut genau das gleiche.
In diesem Fall schon. Aber warum für jede Aufgabe eine neue Form verwenden? Nach meinem Dafürhalten ist, was "Format Specification Mini-Language" anbietet, ungleich mächtiger - und am Ende auch einfacher. Hab mal ein paar Beispiele herausgesucht: # python/python-3.10.13-docs-html/library/string.html#formatspec # Accessing arguments by position: print('{0}{1}{0}'.format('abra', 'cad')) # >>> >>> abracadabra # Accessing arguments by name: print('Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')) # >>> Coordinates: 37.24N, -115.81W # Replacing %s and %r: print("repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')) # >>> repr() shows quotes: 'test1'; str() doesn't: test2 # Accessing arguments’ attributes: c = 3-5j print(('The complex number {0} is formed from the real part {0.real} ' 'and the imaginary part {0.imag}.').format(c)) # >>> The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0. # Using type-specific formatting: import datetime d = datetime.datetime(2010, 7, 4, 12, 15, 58) print('{:%Y-%m-%d %H:%M:%S}'.format(d)) # >>> 2010-07-04 12:15:58
Am 03.07.24 um 11:14 schrieb Hartmut Goebel:
Am 02.07.24 um 20:56 schrieb Andreas Röhler:
print("zaehler: {}".format(zaehler))
Immer wieder sehe ich diese unnötigen und ineffizienten String-Formatierungen bei "print".
print("zaehler:", zaehler)
tut genau das gleiche.
Und wie muster="<tr><td>Vorname:{}</td><td>Nachname:{}</td>\n" f.write(muster.format("Hans","Müller") f.write(muster.format("Lisa","Maier" ) .. handhaben? -- <http://www.hermann-riemann.de>
Am 05.07.24 um 05:47 schrieb Hermann Riemann:
Und wie
muster="<tr><td>Vorname:{}</td><td>Nachname:{}</td>\n"
f.write(muster.format("Hans","Müller") f.write(muster.format("Lisa","Maier" ) ..
handhaben?
Hier ist die Situation eine andere: Du hast eine Vorlage, die Du mehrmals verwendest. Zudem schreibst Du anscheinend in eine Datei und *möchtest* vermutlich *keine* Leerzeichen vor den schließenden Tags (auch wenn sie in HTML egal wären). Wenn das in etwa so vorkommt, wie Du es skizziert hast (das gleiche Muster wird an mehreren Stellen im Code verwendet), würde ich es vermutlich ebenso machen. Wenn Du in eine Datei schreibst (und dafür f.write() verwendest), vermutlich auch so. Wenn Du das in einer Schleife mit print nutzt, würde ich vielleicht sowas verwenden: for vorname, nachname in XXX: print("<tr><td>Vorname:", vorname, "</td><td>Nachname:", nachname, "</td>, sep="", file=f) Allerdings ist das nicht ganz so übersichtlich. Faustregel für mich ist daher eher: Wenn print und Leerzeichen zwischen den Elementen, dann *kein* Muster/Format. Allerdings: wenn der Output übersetzbar sein soll, dann ist man eh schnell wieder bei Mustern :-) -- Regards Hartmut Goebel | Hartmut Goebel |h.goebel@crazy-compilers.com | |www.crazy-compilers.com | compilers which you thought are impossible |
Meine Lösung: #! /usr/bin/env python3 def listlaenge(liste) -> int: if liste == []: return 0 else: return 1 + listlaenge(liste[1:]) a = listlaenge([2, 8, 9, 4]) print("a: {}".format(a)) # >>> a: 4 Am 02.07.24 um 20:56 schrieb Andreas Röhler:
Die untenstehende Funktion soll die Länge einer Liste berechnen. Leider gelingt es nicht, das Ergebnis einer Variablen "a" zuzuweisen. Diese erhält "None". Hat jemand eine Idee?
def listenlaenge (liste, zaehler=0): if liste == []: print("zaehler: {}".format(zaehler)) return zaehler else: zaehler += 1 listenlaenge(liste[1:], zaehler)
# >>> a = listenlaenge([2, 5, 6, 1]) # zaehler: 4 # >>> a # >>> print(a) # None
_______________________________________________ python-de Mailingliste -- python-de@python.org Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an python-de-leave@python.org https://mail.python.org/mailman3/lists/python-de.python.org/ Mitgliedsadresse: andreas.roehler@online.de
participants (6)
-
Andreas Röhler
-
Hartmut Goebel
-
Hermann Riemann
-
Marcel Logen
-
Peter J. Holzer
-
Stephan Herrmann