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-
Aus Summen kürzen nur die Dummen
Code: Alles auswählen
"".join(["Hallo", "du", "da"])
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
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 (former) 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
@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'
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.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
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 (former) Modvoice
Das ist doch wohl schnell selbst gemacht:
@Leonidas:
Lustig ist IMHO nicht nur die Fehlermeldung, sondern auch die Doku:
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!'
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.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.
Wieso erraten?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.
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
@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.
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.
- 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
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Das denke ich mir auch.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.
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.
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.Nocta hat geschrieben:Aber was spricht denn eigentlich dagegen, sum für Strings zuzulassen?
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.
Erstmal würde man bei meiner Version wie gesagt alles durchlaufen bis zu einem Fehler/Exception sobald ein String erkannt wird und dann nochmal neu anfangen und außerdem machen `join()` und `sum()` 2 grundsätzlich unterschiedliche Sachen. Lunar hat das ja schon im Detail erläutert.
Ich find's eigentlich ganz gut, so wie es jetzt ist. Etwas ungewöhnlich finde ich nur, dass der Trenner nicht als Argument innerhalb der Klammer übergeben wird, sondern eben am Anfang stehen muss. Der Hintergrund ist klar: `join()` ist eine Methode der `str`-Klasse. Die Frage ist aber, ob das wirklich so sinnvoll gewählt ist...
Ich find's eigentlich ganz gut, so wie es jetzt ist. Etwas ungewöhnlich finde ich nur, dass der Trenner nicht als Argument innerhalb der Klammer übergeben wird, sondern eben am Anfang stehen muss. Der Hintergrund ist klar: `join()` ist eine Methode der `str`-Klasse. Die Frage ist aber, ob das wirklich so sinnvoll gewählt ist...
- veers
- User
- Beiträge: 1219
- Registriert: Mittwoch 28. Februar 2007, 20:01
- Wohnort: Zürich (CH)
- Kontaktdaten:
lunar hat geschrieben:Man kann Zeichenketten nicht addierenNocta hat geschrieben:Aber was spricht denn eigentlich dagegen, sum für Strings zuzulassen?
Code: Alles auswählen
In [1]: hasattr(str, "__add__")
Out[1]: True
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Und das ist nicht nur höchstwahrscheinlich, sondern sicher flasch. Viel einfacher: die Exception muss man nur auslösen, wenn das zweite Argument ein String ist.snafu hat geschrieben: 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.
Glaub mir, da haben wir ganz andere Sachen zu tun...Vielleicht tobt da ja intern irgendein Kampf, ob man Strings nun annehmen sollte oder nicht.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Und was wenn Tupel, Dicts, Listen, eigene Datentypen drin sind, die ``__add__`` definieren, aber eine Addition mit Strings unsinnig ist?Nocta hat geschrieben:Wieso erraten?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.
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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice