Seite 1 von 3
Warum nimmt sum() keine strings?
Verfasst: Samstag 10. November 2012, 23:31
von mutetella
sum.__doc__ hat geschrieben:Returns the sum of a sequence of numbers (NOT strings)...
Ich kann mir nicht erklären, weshalb die Funktion strings ausschließt. Ist halt so oder gibt es gute Gründe dafür?
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Samstag 10. November 2012, 23:34
von pillmuncher
Re: Warum nimmt sum() keine strings?
Verfasst: Samstag 10. November 2012, 23:36
von BlackJack
@mutetella: Und wenn `sum()` intern durch wiederholte Anwendung von ``+`` implementiert ist, dann muss man damit rechnen, dass das bei Zeichenketten eine ungünstige, nämlich quadratische, Laufzeit hat.
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 10:00
von Sirius3
Hallo mutetella,
in Wirklichkeit ist es sum ziemlich egal, welche Typen es bekommt.
Nur für den Start-Wert wurde eine künstliche Überprüfung eingebaut,
um sum nicht als join zu missbrauchen:
Code: Alles auswählen
class nostring(object):
def __init__(self, s):
self.s=s
def __add__(self, other):
return self.s+other
print sum([' ','nimmt',' ','Strings','!'],nostring('sum'))
# > 'sum nimmt Strings!'
Was mich an sum viel mehr stört, ist, dass es als Startwert immer 0 annimmt,
wenn kein anderer angegeben ist und nicht das erste Element der Liste:
summe = 0 + a + b + ...
Bei selbst-definierten Objekten bei denen eine Summe durchaus Sinn macht,
wird die Funktion dadurch so gut wie unbrauchbar und man muß sich eine eigene
definieren:
Code: Alles auswählen
def summe(seq):
seq=iter(seq)
return sum(seq,seq.next())
Grüße
Sirius
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 10:42
von lunar
@Sirius Deine "summe"-Funktion führt bei leeren Listen zu einer Ausnahme. Implementiere Deinen Typen so, dass "0" als Operand für die Addition unterstützt wird. Natürlich ist das nur bei numerischen Typen sinnvoll, doch für etwas anderes sollte man den Additionsoperator und "sum()" ohnehin nicht einsetzen, zumindest nicht ohne guten Grund.
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 12:30
von mutetella
Es ist Sonntag, es regnet und das Essen ist auch noch nicht fertig...:
Code: Alles auswählen
def timer(func, arg, calls):
results = []
for c in xrange(calls):
start = time.time()
func(arg)
stop = time.time()
results.append(stop - start)
print 'best result of {0} calls: {1}'.format(calls, min(results))
def numeric_sum(iterable):
result = 0
for n in iterable:
result += n
return result
def string_sum(iterable):
result = ''
for n in iterable:
result += n
return result
strings = [s for s in 100000*'a String']
numerics = [int(n) for n in 100000*'512']
Code: Alles auswählen
>>> timer(string_sum, strings, 30)
best result of 30 calls: 0.0892150402069
>>> timer(''.join, strings, 30)
best result of 30 calls: 0.0157160758972
>>> timer(numeric_sum, numerics, 30)
best result of 30 calls: 0.0150220394135
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 12:41
von EyDu
In strings und numerics streckt wahrscheinlich etwas anderes drin als du erwartest

Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 13:37
von mutetella
Ok, also nochmals:
Code: Alles auswählen
#same as above...
strings = []
numerics = []
for i in xrange(100000):
strings.append('a String')
numerics.append(512)
Code: Alles auswählen
>>> timer(string_sum, strings, 30)
best result of 30 calls: 0.0110540390015
>>> sumtime.timer(''.join, strings, 30)
best result of 30 calls: 0.00193405151367
>>> timer(numeric_sum, numerics, 30)
best result of 30 calls: 0.00498700141907
>>> timer(sum, numerics, 30)
best result of 30 calls: 0.000773906707764
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 13:45
von EyDu
Ich glaube, du hast heute einen schlechten Tag erwischt ^^
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 19:17
von mutetella
@EyDu
Schön, wenn's nur ein schlechter Tag wäre... aber zu meiner Schande muss ich gestehen, dass ich nicht wusste, dass man Listen multiplizieren kann...

(wer denkt denn auch an sowas...?)
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Sonntag 11. November 2012, 23:55
von derdon
Aber das eine Funktion namens sum Strings entgegen nehmen könnte, ist für dich völlig intuitiv und es wundert dich sogar, wenn dem nicht so ist

Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 08:36
von mutetella
@derdon
"Völlig intuitiv" ist vielleicht a bisl übertrieben, "entgegen nehmen könnte" trifft es aber schon. Es wunderte mich tatsächlich, weshalb strings von 'sum()' ausdrücklich nicht verarbeitet werden. Liegen für mich und meinem begrenzten Verständnis der Materie ein 1 + 2 doch sehr nahe bei einem 'a' + 'b'. Wobei mir die Erklärungen jetzt schon sehr geholfen haben. Vor allem der Grundsatz bzw. die Empfehlung aus dem Zen of Python, für eine Sache immer möglichst einen Weg zu verwenden.
Dagegen finde ich ein ['a'] * 10 schon 'ne andere Sache, begegnet man (ich?) nicht jeden Tag...
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 09:04
von /me
mutetella hat geschrieben:Dagegen finde ich ein ['a'] * 10 schon 'ne andere Sache, begegnet man (ich?) nicht jeden Tag...

Dann pass bei der Verwendung auf.
Code: Alles auswählen
>>> data = [[0]] * 10
>>> data[0][0] = 1
>>> data
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
Das Verhalten ist zwar völlig logisch, allerdings fällt jeden Tag mindestens einer neu darauf herein.
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 09:10
von lunar
@mutetella 1 + 2 = 3 (Addition), aber 'a' + 'b' = 'ab' (Konkatenation). Siehst Du wirklich Gemeinsamkeiten zwischen diesen Operationen?
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 10:22
von mutetella
@lunar
Ja. Nein. Auch wenn ich das jetzt mangels Wissen und damit mangels Begrifflichkeiten nicht wirklich ausdrücken kann glaube ich schon zu verstehen, dass natürlich der Vorgang, der zu einer '3' führt ein anderer ist, als der zu 'ab'. Aber liegt der Unterschied zwischen der Addition von Zahlen und der Konkatenation von Zeichen letztlich nicht in der Schreibweise des Ergebnisses?
Das Ergebnis von 'a' + 'b' ergibt keinen anderen Buchstaben, weil es diesen nicht gibt und wir das Ergebnis auch ohne diesen ausdrücken können. Die schier unendlichen Kombinationen aus einer begrenzten Auswahl an Buchstaben genügen zur Darstellung.
Das Ergebnis von 1 + 2 ergibt eine andere Zahl, weil innerhalb der Möglichkeiten von 0 - 9 sich ein 1 + 2 durch die 3 darstellen lässt. Sind alle Möglichkeiten erschöpft, müssen wir auch bei Zahlen eine Konkatenation vornehmen, spätestens ab der 10.
Für mich beginnt die Gemeinsamkeit zwischen Addition und Konkatenation also in der Darstellung des Ergebnisses.
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 10:35
von sparrow
@mutatella: Du machst einen Gedankenfehler.
Nehmen wir einen einfachen Fall an:
Eine Zahl ist in diesem einfachsten Fall ein Byte, dessen Bits eine bestimmte "Stellung" haben, die eine Zahl repräsentieren. 1 + 3 = weil:
00000001 + (1)
00000011 = (3)
00000100 (4)
Ein String, also eine Zeichenkette, ist eine Aneinanderreihung von Bytes, wobei ein Byte ein Zeichen kodiert. Soll "a" + "b" zusammengefügt werden ist das Ergebnis also: eine neue Zeichenkette, erstes Byte "a" zweites Byte "b".
Du siehst, die beiden Dinge haben nicht wirklich viel miteinander zu tun.
Gut, du könntest jetzt sagen: hey, beides hat was mit Bytes zu tun! Stimmt, aber dann wäre der Vergleich folgendes:
Und das ist nicht das was du willst, oder?
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 10:37
von BlackJack
@mutetella: Konkatenation bezeichnet das aneinanderhänge von zwei Dingen die zusammen ein neues ergeben, bei dem aber die beiden Teile immer noch erkennbar sind. Also wenn man `x` und `y` konkateniert, kann man danach im Ergebnis immer noch `x` und `y` wiederfinden. Ausserdem ist die Konkatenation nicht kommutativ — ``x + y`` ist was anderes als ``y + x`` (wenn `x ≠ y` gilt). Das ist bei der Addition alles nicht der Fall. Die ist Kommutativ und in der Darstellung findet man die beiden Operanden in der Regel nicht unverändert wieder.
Das ``+`` ist für Addition auch *die* Darstellung für den Operator. Sowohl in der Mathematik, als auch bei der überwiegenden Mehrzahl der Programmiersprachen. Für die Konkatenation von Zeichenketten gibt es neben ``+`` einen ganzen Zoo von anderen Möglichkeiten. Beispiele: ``&`` (BASIC-Dialekte), ``.`` (PHP), ``..`` (Io), ``~`` (D), ``#`` (C-Präprozessor), ``++`` (Haskell), ``,`` (4GL).
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 10:39
von sparrow
|| in SQL (keine Ahnung ob das Standard ist

)
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 11:24
von mutetella
Vielen Dank für Eure Erklärungen die für mich wirklich sehr interessant sind. Jetzt wird mir auch ein wenig klarer, wo der Unterschied zwischen Addition und Konkatenation im Vorgang liegt.
[
Hier stand bis kurzem noch viel bla bla...]
Ich wollte noch nicht so schnell aufgeben, weil sich für mich Addition und Konkatenation zumindest in der Darstellung immer noch sehr ähnlich anfühlen. Aber es ist nur noch ein Gefühl, wirkliche Argumente hab' ich jetzt natürlich keine mehr...
mutetella
Re: Warum nimmt sum() keine strings?
Verfasst: Montag 12. November 2012, 11:40
von EyDu
Du kannst dir die Konkatenation als Änderung in der Dimension veranschaulichen. Bei der Addition von zwei Objekten mit der Dimension n kommt am Ende ein Objekt mit der Dimension n wieder heraus. Bei der Konkatenation eines Objekts der Dimension n mit einem Objekt der Dimension m erhältst du am Ende ein Objekt mit der Dimension n+m.
Bei Zahlen (Dimension n=1) ist die Sache einfach:
42 + 23 = 65
Bei Vektoren (hier mal als Dimension n=3):
[1, 2, 3] + [4, 5, 6] = [5, 7, 9]
Und als Konkatenation:
[1, 2, 3] ++ [4, 5, 6] = [1, 2, 3, 4, 5, 6]
Das alles könnte man jetzt noch in mathematische Strukturen packen. Allerdings reichen sowohl das Fehlen der Kommutattivität, als auch die Änderung der Dimension aus, um zu zeigen, dass die Operationen verschieden sind.