Aus Summen kürzen nur die Dummen
Aus Summen kürzen nur die Dummen
Hallo,
sum([1,2,3]) funktioniert wunderbar, aber sum(["hallo", " du", " da!"]) nicht.
Gibt es keinen Python Standard, um strings aus Listen zu addieren?
Immerhin "funktioniert "+"das hier" ohne Probleme.
Grüße,
4bit-
sum([1,2,3]) funktioniert wunderbar, aber sum(["hallo", " du", " da!"]) nicht.
Gibt es keinen Python Standard, um strings aus Listen zu addieren?
Immerhin "funktioniert "+"das hier" ohne Probleme.
Grüße,
4bit-
Code: Alles auswählen
"".join(["Hallo", "du", "da"])
Genauer: sum nimmt zwei Argumente, einmal das Iterable das aufsummiert werden soll und einen Startwert. Dieser Startwert ist standardmäßig 0 und daher kommt "TypeError: unsupported operand type(s) for +: 'int' and 'str'" (``0 + "Hallo"`` funktioniert eben nicht). Wenn man nun aber als zweiten Parameter den leeren String angibt, "", dann kommt "TypeError: sum() can't sum strings [use ''.join(seq) instead]", wo einem explizit gesagt wird was zu tun ist. Lustige Fehlermeldung 

My god, it's full of CARs! | Leonidasvoice vs Modvoice
Es geht auch anders

Code: Alles auswählen
In [676]: from operator import add
In [677]: reduce(add, ['Hallo ', 'du ', 'da'])
Out[677]: 'Hallo du da'
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Re: Aus Summen kürzen nur die Dummen
@derdon: Argh!
Und hier nochmal in schön
Edit: Und hier in einem Rutsch:

Code: Alles auswählen
In [739]: join_string = lambda strings, sep='': reduce(lambda a, b: (lambda a, b, sep: a + sep + b)(a, b, sep), strings)
In [740]: join_string(['Hallo', 'du', 'da'])
Out[740]: 'Halloduda'
In [741]: join_string(['Hallo', 'du', 'da'], ' ')
Out[741]: 'Hallo du da'
Edit: Und hier in einem Rutsch:
Code: Alles auswählen
In [745]: (lambda strings, sep='': reduce(lambda a, b: (lambda a, b, sep: a + sep + b)(a, b, sep), strings))(('Hallo', 'du', 'da'), ' ')
Out[745]: 'Hallo du da'
Könnte man die sum Funktion nicht so schreiben, dass sie als Startwert einen Typ nimmt, der sowohl Strings als auch Integer (und sonstige numerische Datentypen) addieren kann bzw jeweils den Datentyp annimmt, der benötigt wird?
Strings in Listen zu addieren zu können, wäre ja eigentlich logisch, weil man sie ja auch mittels + addieren kann.
Wenn Strings und Zahlen gemixt sind, müssten die Zahlen halt als String angesehn werden, anders macht das dann wieder keinen Sinn.
Strings in Listen zu addieren zu können, wäre ja eigentlich logisch, weil man sie ja auch mittels + addieren kann.
Wenn Strings und Zahlen gemixt sind, müssten die Zahlen halt als String angesehn werden, anders macht das dann wieder keinen Sinn.
Also soll quasi die Funktion erraten was du vor hast? Das klingt nach einer sehr schlechten Idee. Explicit is better than implicit.
Und Strings in Listen sollte man eben nicht addieren, genau dafür gibt es ja auch ``join``, was das bevorzugte Werkzeug ist (und die Fehlermeldung sagt das auch so).
Und Strings in Listen sollte man eben nicht addieren, genau dafür gibt es ja auch ``join``, was das bevorzugte Werkzeug ist (und die Fehlermeldung sagt das auch so).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Das ist doch wohl schnell selbst gemacht:
@Leonidas:
Lustig ist IMHO nicht nur die Fehlermeldung, sondern auch die Doku:
Vielleicht tobt da ja intern irgendein Kampf, ob man Strings nun annehmen sollte oder nicht.
Code: Alles auswählen
In [6]: def new_sum(sequence, start=0):
...: try:
...: return sum(sequence, start=start)
...: except TypeError:
...: return ''.join(sequence)
...:
...:
In [7]: new_sum(["hallo", " du", " da!"])
Out[7]: 'hallo du da!'
@Leonidas:
Lustig ist IMHO nicht nur die Fehlermeldung, sondern auch die Doku:
Docstring:
sum(sequence, start=0) -> value
Returns the sum of a sequence of numbers (NOT strings) plus the value
of parameter 'start'. When the sequence is empty, returns start.
Vielleicht tobt da ja intern irgendein Kampf, ob man Strings nun annehmen sollte oder nicht.

Leonidas hat geschrieben:Also soll quasi die Funktion erraten was du vor hast? Das klingt nach einer sehr schlechten Idee. Explicit is better than implicit.
Wieso erraten?
Eindeutig definiert:
Sind Strings vorhanden, werden Strings addiert.
Sind (nur) Zahlen vorhanden, werden die Zahlen summiert.
Ist beides vorhanden, wird alles als String angesehen und addiert.
Das einzige wirkliche Problem würde ich darin sehen, dass das die sum-Methode wahrscheinlich deutlich verlangsamen würde, wenn man große Listen erstmal nach Strings überprüfen muss, damit die Funktion entscheiden kann, was zu tun ist.
Also Beispielsweise bei Listen, die so aussehen:
Code: Alles auswählen
[1, 2, 3, 4, 5, ..., 999999999, "a", "b"]
Aber man könnte den 3. Punkt auch einfach weglassen und spart sich diese Probleme. Es ist eh nicht so "schön" einfach Strings und Zahlen als Strings zu addieren und wahrscheinlich auch unnötig. Dann nimmt man sich einfach das erste Element und addiert den rest drauf. Wenn Strings und Zahlen vermischt sind kann man dann ja immer noch einen Error ausgeben

- veers
- User
- Beiträge: 1219
- Registriert: Mittwoch 28. Februar 2007, 20:01
- Wohnort: Zürich (CH)
- Kontaktdaten:
Code: Alles auswählen
TypeError: sum() can't sum strings [use ''.join(seq) instead]

Jonas
My Website - 29a.ch
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
snafu hat geschrieben:@Nocta:
Ich kenne die genaue Implementierung von `sum()` nicht, aber höchstwahrscheinlich wird der `TypeError` da auch erst geworfen, wenn die 1 Million Elemente durchlaufen wurden und er auf einen String stößt.
Das denke ich mir auch.
Aber wenn man zulassen will, dass Strings und Zahlen gemixt addiert werden können, muss man im vorhinein wissen, ob dies passieren soll, weil die Zahlen ja sonst alle summiert würden, anstatt als String addiert zu werden. Deshalb wäre sum() für Strings und Zahlen gleichzeitig wohl zu unperformant (je nachdem, was für eine Liste es ist), um es zuzulassen.
Aber was spricht denn eigentlich dagegen, sum für Strings zuzulassen?
Also so in etwa wie du (snafu) es als Codebeispiel gepostet hast.
@veers: Verstehn tut die glaube ich jeder. Und es versteht auch jeder, dass es join() gibt. Aber ich sehe keine Notwendigkeit, das in 2 Funktionen (sum für Zahlen und join für Strings) aufzuteilen. Aber wenn jemand ein (gerne auch mehrere) Argument dafür hat, ändere ich meine Meinung gerne.
Nocta hat geschrieben:Aber was spricht denn eigentlich dagegen, sum für Strings zuzulassen?
Man kann Zeichenketten nicht addieren, die Summe ist eine arithmetische Funktion. Zeichenkette kann man allenfalls zusammenfügen. sum() für Zeichenketten ist einfach unlogisch. Zudem wäre das fehleranfällig, da eine vergessene Typkonvertierung anstatt einer geordneten Ausnahme eine unerwartete Konkatenation zur Folge hätte. Unpraktisch wäre es auch, da man Zeichenketten oft auch mit bestimmten Trennzeichen zusammenfügen möchte (z.B. '\n'.join(sequence)). Die Implementierungen wären auch komplett unterschiedlich, zumindest, wenn man sie effizient gestalten möchte.
Schlussendlich aber ist diese Diskussion eh müßig. Das Verhalten ist durch die Dokumentation nun mal so festgelegt, also wirst du damit leben müssen. Für Diskussionen um Veränderungen der Bibliothek bzw. der Sprache ist die python-dev-Liste da.
Wer ist online?
Mitglieder in diesem Forum: __deets__, Bing [Bot]