Python-Spickzettel für PHP-Entwickler
-
- User
- Beiträge: 5
- Registriert: Montag 10. April 2006, 17:29
- Wohnort: Kirchen (Sieg)
- Kontaktdaten:
Hallo!
Ich habe ein kleines Spickzettel-PDF erstellt, in dem die meiner
Meinung nach wichtigsten Unterschiede, Fallstricke und Standardfunktionen dokumentiert sind. Ich selbst habe während meiner Einstiegsphase in Python immer wieder nach diesen Schnipseln gesucht, möge es zukünftigen Einsteigern eine kleine Hilfe sein:
http://www.experimentierkasten.de/python_php.pdf (~120 KB)
Ich bitte um Korrekturen und Erweiterungsvorschläge. Was für meinen
Geschmack jetzt schon fehlt, ist die Anlage assoziativer Arrays. Insgesamt soll das Dokument nicht grösser als eine Doppelseite Din-A4 werden, aber bis jetzt ist mit einer Seite noch genug Platz für Ergänzungen.
Danke und Gruß,
Marcel
Ich habe ein kleines Spickzettel-PDF erstellt, in dem die meiner
Meinung nach wichtigsten Unterschiede, Fallstricke und Standardfunktionen dokumentiert sind. Ich selbst habe während meiner Einstiegsphase in Python immer wieder nach diesen Schnipseln gesucht, möge es zukünftigen Einsteigern eine kleine Hilfe sein:
http://www.experimentierkasten.de/python_php.pdf (~120 KB)
Ich bitte um Korrekturen und Erweiterungsvorschläge. Was für meinen
Geschmack jetzt schon fehlt, ist die Anlage assoziativer Arrays. Insgesamt soll das Dokument nicht grösser als eine Doppelseite Din-A4 werden, aber bis jetzt ist mit einer Seite noch genug Platz für Ergänzungen.
Danke und Gruß,
Marcel
Ich finde das cool.
Ich habe keine ahnung wie "pythonic" es ist, aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Bei den Rechenproblemen halte ich es auch für stilvoller die Null aus zu schreiben: 7.0/4.0
OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.
Edit:
Wie unhöflich von mir - herzlich willkommen im Forum!
Ich habe keine ahnung wie "pythonic" es ist, aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Bei den Rechenproblemen halte ich es auch für stilvoller die Null aus zu schreiben: 7.0/4.0
OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.
Edit:
Wie unhöflich von mir - herzlich willkommen im Forum!
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi Marcel!marcel.normann hat geschrieben:Ich bitte um Korrekturen und Erweiterungsvorschläge.
Nette Seite, aber die Wahrheitswerte würde ich anders beschreiben:
Falsch:
0; False; ""; []; (); {}
Richtig:
Alles was nicht *Falsch* ist:
-3; 1; 2; 3; True; "asdf"; [0]; (0); {0: 0}
mfg
Gerold

Edit: Sorry, hatte einen Beistrich zu viel.
Zuletzt geändert von gerold am Montag 10. April 2006, 22:03, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
-
- User
- Beiträge: 5
- Registriert: Montag 10. April 2006, 17:29
- Wohnort: Kirchen (Sieg)
- Kontaktdaten:
Danke erst mal an alle für die Willkommensgrüsse.
>>> False == 0
False
>>> True == ""
False
Oder habe ich jetzt was falsch verstanden?
Mal gucken wie ich das mit dem Platz mache. Für eine Doppelseite habe ich viel zu wenig, für eine einzelne Seite etwas zuviel. Die assoziativen Arrays sollen aber auf jeden Fall noch mit rein. Vielleicht nehme ich beim PHP-Code die if-Klammern raus, was ich eigentlich sehr hässlich finde.
Mal eine Frage nebenbei: Gibt es eigentlich in Pyhton Ternär-Operatoren, also sowas wie:
echo ('a' == 'a' ? 'a' : 'b');
?
Gruß, Marcel
Mir gefällt die Version mit Klammern nicht, weil hier dieses seltsame Komma am Ende auftaucht. PHP-Umsteiger kennen den Unterschied zwischen Tupel/Liste ja garnicht, deshalb fand ich es sinnvoll, die gängigen Methoden aufzuschreiben.Mr_Snede hat geschrieben:...aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Ich werde es als zusätzliche Schreibweise aufnehmen.Mr_Snede hat geschrieben:Bei den Rechenproblemen halte ich es auch für stilvoller die Null aus zu schreiben: 7.0/4.0
Sicher?gerold hat geschrieben:Falsch:
0; False; ""; []; (,); {}
Richtig:
Alles was nicht *Falsch* ist:
-3; 1; 2; 3; True; "asdf"; [0]; (0); {0: 0}
>>> False == 0
False
>>> True == ""
False
Oder habe ich jetzt was falsch verstanden?
Mal gucken wie ich das mit dem Platz mache. Für eine Doppelseite habe ich viel zu wenig, für eine einzelne Seite etwas zuviel. Die assoziativen Arrays sollen aber auf jeden Fall noch mit rein. Vielleicht nehme ich beim PHP-Code die if-Klammern raus, was ich eigentlich sehr hässlich finde.
Mal eine Frage nebenbei: Gibt es eigentlich in Pyhton Ternär-Operatoren, also sowas wie:
echo ('a' == 'a' ? 'a' : 'b');
?
Gruß, Marcel
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Ja.Oder habe ich jetzt was falsch verstanden?
Python vergleicht bei einem Vergleich nicht den Wahrheitswert des Objekts, sondern die Objekte selbst. Das Objekt False ist sicherlich nicht gleich dem Objekt leere Zeichenkette (besser gesagt, es hat sicherlich nicht den gleichen Wert, der Vergleich ob es das selbe Objekt ist wird mittels is gemacht).
Beide sind aber, als Wahrheitswert ausgewertet, falsch.
Was Du aber machen kannst um rauszufinden was für einen Wahrheitswert ein Objekt hat:
Code: Alles auswählen
print bool(False)
print bool("")
print bool([])
...
Code: Alles auswählen
if "":
print "True"
else:
print "False"
Zum ternären Operator: Ja und nein.
Einen ternären Operator per se gibt es nicht, es gibt aber eine ganze Menge Möglichkeiten (also Idiome) etwas derartiges zu schreiben. Zum Beispiel:
Code: Alles auswählen
x = 1
print x and "wahr" or "falsch"
print ["falsch","wahr"][bool(x)]
print {False:"falsch",True:"wahr"}[bool(x)]
print [lambda:"falsch",lambda:"wahr"][bool(x)]()
Code: Alles auswählen
x = 1
print x and 0 or 1
--- Heiko.
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
Bis ptyhon2.3 gabs gar kein True/False. Da wurde einfach ein objekt auf länge > 0, obj.__nonzero__() == 1 ausgewertet.marcel.normann hat geschrieben:Sicher?
>>> False == 0
False
>>> True == ""
False
Oder habe ich jetzt was falsch verstanden?
ja und nein.Mal eine Frage nebenbei: Gibt es eigentlich in Pyhton Ternär-Operatoren, also sowas wie:
echo ('a' == 'a' ? 'a' : 'b');
In python2.5 gibts welche (ich glaub schon implementiert), aber es gibt folgende "Lösung":
Code: Alles auswählen
>>> True and "TRUE" or "FALSE"
'TRUE'
>>> False and "TRUE" or "FALSE"
'FALSE'
TUFKAB – the user formerly known as blackbird
-
- User
- Beiträge: 5
- Registriert: Montag 10. April 2006, 17:29
- Wohnort: Kirchen (Sieg)
- Kontaktdaten:
Man lernt nie aus. Danke für den Tipp. PHP castet bei solchen Vergleichen ziemlich freizügig - was ich in der Regel kofortabel finde, jedoch auch zu unerwünschten Ergebnissen führen kann.modelnine hat geschrieben:Python vergleicht bei einem Vergleich nicht den Wahrheitswert des Objekts, sondern die Objekte selbst. Das Objekt False ist sicherlich nicht gleich dem Objekt leere Zeichenkette (besser gesagt, es hat sicherlich nicht den gleichen Wert, der Vergleich ob es das selbe Objekt ist wird mittels is gemacht).
Ich lasse die Liste aber wahrscheinlich trotzdem in der jetzigen Form, da es mir vor allem um die korrekte Groß-/Kleinschreibung der beiden Werte geht.
Gruß, Marcel
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Jupp. Man sagt deswegen auch dass Python stark und dynamisch typisiert ist, während PHP (und auch Perl) schwach und dynamisch typisiert sind.PHP castet bei solchen Vergleichen ziemlich freizügig - was ich in der Regel kofortabel finde, jedoch auch zu unerwünschten Ergebnissen führen kann.
Im Endeffekt kannst Du bei Python davon ausgehen dass eine Typkonversion (außer bei Zahlen) niemals ohne Dein direktes Eingreifen stattfinden wird.
--- Heiko.
Habe selber nie ein Komma am Ende benutzt:marcel.normann hat geschrieben:Mir gefällt die Version mit Klammern nicht, weil hier dieses seltsame Komma am Ende auftaucht.Mr_Snede hat geschrieben:...aber mir gefällt die Zuweisung von Werten in ein Tupple ohne die Klammern nicht.
Code: Alles auswählen
>>> mytuple = ('a','b','c')
>>> mytuple
('a', 'b', 'c')
Im Python Tutorial werden Tuples ohne Komma am Ende verwendet:
http://docs.python.org/tut/node7.html#S ... 0000000000
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Der einzige Ort wo man mit einer Klammer abschließen muß ist wenn man ein Tupel der Länge eins haben will:
Die Klammern haben in Python nämlich einmal die Bedeutung eine Berechnung zu gruppieren (also Präzedenz zu verteilen), und zum anderen die Bedeutung dass ein Tupel daraus gemacht wird. Sonst, wenn man ein Tupel erstellen will, ist es gute Praktik immer Klammern zu verwenden. Ohne Klammern macht man eigentlich nur wenn man direkt Tupel-Unpacking verwenden will, wie zum Beispiel in:
um zwei Variablen zu vertauschen.
Ein (halbwegs abschreckendes) Beispiel für Tupel-Entpacken:
http://www.python-forum.de/post-34778.html#34778
Code: Alles auswählen
print repr(("hello"))
print repr(("hello",))
Code: Alles auswählen
x, y = y, x
Ein (halbwegs abschreckendes) Beispiel für Tupel-Entpacken:
http://www.python-forum.de/post-34778.html#34778
--- Heiko.
Das Komma taucht nur auf, wenn das Tupel nur ein Wert besitzt, weil es sonst ein String wäre:
/edit: Oh ich sehe gerade Modelnine war etwas schneller! 
Code: Alles auswählen
a=('a',)
b=('b')
type(a)
(type 'tupel')
type(b)
(type 'str')

mfg
Thomas :-)
Thomas :-)
-
- User
- Beiträge: 5
- Registriert: Montag 10. April 2006, 17:29
- Wohnort: Kirchen (Sieg)
- Kontaktdaten:
Dafür liebe ich Python: Jeden Tag entdeckt man etwas, womit man seinen Code noch pythonischer machen kann
Das letzte Komma beim Tuple nehme ich dann raus, ansonsten lasse ich beide Schreibweisen drin. Vielleicht nehme ich sogar nochg ein Tuple mit einem Element hinzu.
Das PDF hat natürlich keinerlei Anspruch in irgendeiner Weise komplett zu sein. Es soll nur PHP-Entwicklern eine erste Hilfe an die Hand geben, um erste kleine Codebröckchen zu schreiben. Die dargestellten Lösungen sollten einerseits PHP-nah sein, aber gleichzeitg auch auf Pyhton-Leckerlies hinweisen.
Gruß, Marcel
Edit: Die neue Version ist unter gleicher URL online

Das letzte Komma beim Tuple nehme ich dann raus, ansonsten lasse ich beide Schreibweisen drin. Vielleicht nehme ich sogar nochg ein Tuple mit einem Element hinzu.
Das PDF hat natürlich keinerlei Anspruch in irgendeiner Weise komplett zu sein. Es soll nur PHP-Entwicklern eine erste Hilfe an die Hand geben, um erste kleine Codebröckchen zu schreiben. Die dargestellten Lösungen sollten einerseits PHP-nah sein, aber gleichzeitg auch auf Pyhton-Leckerlies hinweisen.
Gruß, Marcel
Edit: Die neue Version ist unter gleicher URL online
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
So, ein paar kleine Korrekturen/Ergänzungen noch:
1)
print "abcd".replace("a","b") ---> # bbcd
2)
Rechenprobleme ist falsch. Sollte eher sowas wie "Integer-Division" heißen (bei der Python aus historischen Gründen die Typen nicht promoviert ---> float, wenn das Ergebnis nicht in einen Integer passt).
3)
print "Die Zahl ist %s" % (zahl,) hat nichts mit Zeichenverkettung zu tun, sondern bemüht den String-Formatting-Operator von Python (eben das %), der ähnlich wie printf("blah %s, %s",blubb,blubb) in C funktioniert, wobei %s bedeutet dass das Objekt zuerst mittels str(zahl) in einen String gecastet wird bevor es eingefügt wird, es gibt aber zum Beispiel %f um Floats zu formatieren, %i um Integer zu formatieren, etc. Unabhängig davon gibts in Python auch nichts vergleichbares wie "blah $blubb hastenichgesehen" in PHP; das geht eben nur über String-Formatting, womit ich %s in Python am ehesten vergleichen würde.
4)
+= ist im Normalfall ungleich .=, die Äquivalenz gilt nur für Zeichenketten. Denn "$a .= $b;" in PHP für zwei Zahlen liefert eine String-Konkatenation der beiden Zahlen, während in Python einfach die Summe der beiden Zahlen bei "a += b" gebildet wird und an a gebunden ist.
5)
'''
blah
'''
ist kein mehrzeiliger Kommentar, sondern einfach ein mehrzeiliger String. Da Du ihn nichts zuweist fungiert er wie ein Kommentar, es sollte aber irgendwie klarer herauszustellen sein dass ''' ''' identisch ist mit """ """ (so wie " und ' in Python für Strings absolut identisch sind, man benutzt den einen wenn man den anderen schreiben will, sprich es gibt keine Unterschiede beim Escaping zwischen den beiden Arten der String-Schreibweise, dafür gibts Präfixe wie u"" für Unicode-Strings, und r"" für "Rohe-Strings", die sich mehr oder weniger wie Strings ohne Escaping-Regeln verhalten).
6)
for-Schleife: Python besitzt keine Zählschleife, Python besitzt nur so etwas was ich Iterator-Schleife nennen würde (also was über alle Elemente eines gegebenen Objekts iteriert). range(5) -> [0,1,2,3,4] (also die Liste mit den Elementen 0-4), und über diese Liste wird iteriert, ein Element nach dem anderen. Ganz allgemein kann man über viele Dinge iterieren, wie zum Beispiel:
for x in "hello":
print x
Oder auch:
for x in {"blah":"blubb","asta":"lavista","baby":"!"}:
print x
(ausprobieren
!) Diesen massiven Unterschied sollte man sinnigerweise irgendwie darstellen würde ich mal sagen...
7)
Wahrheitswerte vergleicht man in Python nicht. Sondern, man benutzt logische Operatoren. Wenn zum Beispiel gefragt ist dass zwei Objekte wahr sind, dann benutzt man "and", wenn eines der beiden mindestens wahr sein soll "or", oder eben auch not.
8 )
Soweit ich weiß heißt das Ding nicht Trinitäts-Operator, sondern auch auf Deutsch Ternärer Operator, einfach weil er drei Argumente nimmt.
Wenn mir noch was einfällt poste ich es gerne (wenn Du noch was hören magst
), und nimm mir das viele Geschreibsel nicht übel; ich weiß dass es teilweise nicht für so einen Cheatsheet geeignet ist, aber vielleicht lässt sich trotzdem was davon integrieren, eben weil Python in einigen/vielen Dingen eine komplett andere Philosophie als PHP verfolgt, und man sowas durchaus rausstellen sollte aus meiner Sicht.
1)
print "abcd".replace("a","b") ---> # bbcd
2)
Rechenprobleme ist falsch. Sollte eher sowas wie "Integer-Division" heißen (bei der Python aus historischen Gründen die Typen nicht promoviert ---> float, wenn das Ergebnis nicht in einen Integer passt).
3)
print "Die Zahl ist %s" % (zahl,) hat nichts mit Zeichenverkettung zu tun, sondern bemüht den String-Formatting-Operator von Python (eben das %), der ähnlich wie printf("blah %s, %s",blubb,blubb) in C funktioniert, wobei %s bedeutet dass das Objekt zuerst mittels str(zahl) in einen String gecastet wird bevor es eingefügt wird, es gibt aber zum Beispiel %f um Floats zu formatieren, %i um Integer zu formatieren, etc. Unabhängig davon gibts in Python auch nichts vergleichbares wie "blah $blubb hastenichgesehen" in PHP; das geht eben nur über String-Formatting, womit ich %s in Python am ehesten vergleichen würde.
4)
+= ist im Normalfall ungleich .=, die Äquivalenz gilt nur für Zeichenketten. Denn "$a .= $b;" in PHP für zwei Zahlen liefert eine String-Konkatenation der beiden Zahlen, während in Python einfach die Summe der beiden Zahlen bei "a += b" gebildet wird und an a gebunden ist.
5)
'''
blah
'''
ist kein mehrzeiliger Kommentar, sondern einfach ein mehrzeiliger String. Da Du ihn nichts zuweist fungiert er wie ein Kommentar, es sollte aber irgendwie klarer herauszustellen sein dass ''' ''' identisch ist mit """ """ (so wie " und ' in Python für Strings absolut identisch sind, man benutzt den einen wenn man den anderen schreiben will, sprich es gibt keine Unterschiede beim Escaping zwischen den beiden Arten der String-Schreibweise, dafür gibts Präfixe wie u"" für Unicode-Strings, und r"" für "Rohe-Strings", die sich mehr oder weniger wie Strings ohne Escaping-Regeln verhalten).
6)
for-Schleife: Python besitzt keine Zählschleife, Python besitzt nur so etwas was ich Iterator-Schleife nennen würde (also was über alle Elemente eines gegebenen Objekts iteriert). range(5) -> [0,1,2,3,4] (also die Liste mit den Elementen 0-4), und über diese Liste wird iteriert, ein Element nach dem anderen. Ganz allgemein kann man über viele Dinge iterieren, wie zum Beispiel:
for x in "hello":
print x
Oder auch:
for x in {"blah":"blubb","asta":"lavista","baby":"!"}:
print x
(ausprobieren

7)
Wahrheitswerte vergleicht man in Python nicht. Sondern, man benutzt logische Operatoren. Wenn zum Beispiel gefragt ist dass zwei Objekte wahr sind, dann benutzt man "and", wenn eines der beiden mindestens wahr sein soll "or", oder eben auch not.
8 )
Soweit ich weiß heißt das Ding nicht Trinitäts-Operator, sondern auch auf Deutsch Ternärer Operator, einfach weil er drei Argumente nimmt.
Wenn mir noch was einfällt poste ich es gerne (wenn Du noch was hören magst

--- Heiko.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Doch, seit PEP 292 (= Python 2.4) hat Python etwas vergleichbares, die Template-Strings. Verhält sich wie eben ein sehr simples Templating-System. Es ist zwar nicht exakt gleich wie z.B "Der Wert ist #{value}" in Ruby-Strings zum Beispiel, aber vergleichbar.modelnine hat geschrieben:Unabhängig davon gibts in Python auch nichts vergleichbares wie "blah $blubb hastenichgesehen" in PHP; das geht eben nur über String-Formatting, womit ich %s in Python am ehesten vergleichen würde.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
-
- User
- Beiträge: 670
- Registriert: Sonntag 15. Januar 2006, 18:42
- Wohnort: Celle
- Kontaktdaten:
Stimmt. Nur, da sie nicht intrinsisch in der Sprache eingebaut sind (wie String-Formatting), sondern man eine separate Klasse braucht, seh ich sie eigentlich nicht als direkten Vergleich zu "blah $blubb xyz", welches eben keine zusätzlichen Sprachelemente benötigt (auch wenn es von der Syntax her ähnlich ist, aber das krieg ich mit String-Formatting und dicts auch hin dass es so ähnlich aussieht).Doch, seit PEP 292 (= Python 2.4) hat Python etwas vergleichbares, die Template-Strings.
--- Heiko.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Okay, dann versuch ichs noch damit:
Auch nicht ganz vergleichbar, aber immerhin in der Sprache eingebaut.
Code: Alles auswählen
value = 10
print 'Value %(value)s' % locals()
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Ein Python-C Spickzettel ist nicht so einfach, weil C nicht über so "fortgeschrittene" Datentypen verfügt, wie Python oder sogar PHP.Python Master 47 hat geschrieben:Ich fände sowas für Pythn-C/C++ sehr gut!Mr_Snede hat geschrieben: OT:
wäre lustig sowas auch für Python - Ruby bzw Python - Perl zu haben.
C Felder kennen zum Beispiel ihre Länge nicht, die muss man sich entweder gesondert merken, oder eine Endmarkierung benutzen, die nicht regulär im Feld vorkommen darf. Bei Zeichenketten, die eigentlich nur Felder vom Typ `char` sind, ist das zum Beispiel das Nullbyte.
Während ein Feld anlegen noch einfach ist...
Code: Alles auswählen
char *array[] = {"foo", "bar", "frobnitz"};
Code: Alles auswählen
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
typedef int bool;
typedef int (*cmp_func)(const void *a, const void *b);
bool in_array(const void **array,
const unsigned int array_size,
const void *needle,
const cmp_func cmp)
{
unsigned int i;
for (i=0; i < array_size; ++i) {
if (cmp(needle, array[i]) == 0) {
return TRUE;
}
}
return FALSE;
}
Code: Alles auswählen
if (in_array(array, 3, "bar", strcmp)) {
puts("Ist drin");
}
`join()` ist dann wegen der Speicherverwaltung, um die man sich bei C selbst kümmern muss, noch umfangreicher. Für das Ergebnis muss man soviel Speicher anfordern, das alle Zeichenketten plus den Seperatoren hineinpassen, also muss man in einem ersten Schritt ersteinmal die Längen der einzelnen Zeichenketten herausfinden. Dann kann man den Speicher anfordern und die einzelnen Zeichenketten und Seperatoren dort hin kopieren.
Code: Alles auswählen
char* str_join(const char *separator,
const char **strings,
const unsigned int array_size)
{
unsigned int i, separator_length, *lengths;
unsigned int new_size;
char *result, *ptr;
separator_length = strlen(separator);
new_size = 1 + (array_size - 1) * separator_length;
lengths = malloc(array_size * sizeof(unsigned int));
for (i=0; i < array_size; ++i) {
lengths[i] = strlen(strings[i]);
new_size += lengths[i];
}
result = malloc(new_size * sizeof(char));
ptr = result;
for (i=0; i < array_size; ++i) {
memcpy(ptr, strings[i], lengths[i]);
ptr += lengths[i];
if (i != array_size - 1) {
memcpy(ptr, separator, separator_length);
ptr += separator_length;
}
}
*ptr = '\0';
free(lengths);
return result;
}

Anwendung der Funktion:
Code: Alles auswählen
char *str;
str = str_join("-", array, 3);
puts(str);
free(str);

Code: Alles auswählen
char** str_split(const char *string,
const char *separator,
unsigned int *result_size)
{
unsigned int i, str_length, separator_length;
char **result, *str, *start, *end;
str = strdup(string);
str_length = strlen(str);
separator_length = strlen(separator);
i = 0;
result = malloc((str_length / 2) * sizeof(char**));
start = str;
while ((end = strstr(start, separator))) {
*end = '\0';
result[i++] = strdup(start);
start = end + separator_length;
}
result[i++] = strdup(start);
free(str);
result = realloc(result, i * sizeof(char**));
*result_size = i;
return result;
}
Code: Alles auswählen
char **strings;
unsigned int i, size;
strings = str_split("foo<->bar<->frobnitz", "<->", &size);
for (i=0; i < size; ++i) {
puts(strings[i]);
/* free(strings[i]); */
}
/* free(strings); */
Ob das in C++ so viel einfacher wird, wage ich zu bezweifeln. Klar man hat Objekte, aber mit Objekten und Templates bekommt man auch sehr viel mehr Komplexität mit der man sich herumschlagen muss.
Einer Python-Liste am nächsten kommt wohl der `vector` in C++:
Wenn man das temporäre `char`-Feld nicht haben möchte, dann könnte man alternativ auch die drei Zeichenketten einzeln an den `vector` anhängen:
Schon wenn man den ``in`` Operator aus Python als Funktion für einen beliebigen Container aus der STL von C++ implementieren möchte, wird man mit Templates konfrontiert:
Man kann `find()` natürlich auch direkt in ``if``-Abfragen benutzen. Den Fall habe ich im folgenden auskommentiert:
Die Länge eines Containers kann man natürlich sehr schön ermitteln, da die Objekte eine entsprechende Methode besitzen:
`join()` und `split()` muss man sich aber selbst schreiben.
Zu benutzen sind die beiden so:
Ob das nun einfacher ist als bei C!? Ich finde C++ auf jeden Fall hässlicher. Insbesondere Fehlermeldungen, die mit Templates zusammenhängen und die Komplexität von Templates im allgemeinen. Ein verkorkster Versuch das starre Typsystem aufzubrechen, IMHO.
Zu den Template-Fehlermeldungen hier ein nettes Beispiel, welches mir beim Schreiben der Beispiele untergekommen ist:
Da weiss man doch sofort was man falsch gemacht hat, oder!?
Nochmal zum PHP-Python Spickzettel: Bei dem `substr()` Beispiel sollte auf jeden Fall ein Satz erklären, dass die beiden Argumente bei PHP Start und Länge, bei Python aber Start und Ende darstellen. Aus den angegebenen Beispielen wird das nämlich nicht unbedingt klar.
Einer Python-Liste am nächsten kommt wohl der `vector` in C++:
Code: Alles auswählen
char *tmp[] = {"foo", "bar", "frobnitz"};
vector<string> array(&tmp[0], &tmp[3]);
Code: Alles auswählen
vector<string> array;
array.push_back("foo");
array.push_back("bar");
array.push_back("frobnitz");
Code: Alles auswählen
template<class Iterable, class T>
bool contains(Iterable iterable, const T& element)
{
return find(iterable.begin(), iterable.end(), element) != iterable.end();
}
Code: Alles auswählen
// if (find(array.begin(), array.end(), "bar") != array.end()) {
if (contains(array, "bar")) {
cout << "Ist drin" << endl;
}
Code: Alles auswählen
cout << array.size() << endl;
Code: Alles auswählen
template<class Iter>
string join(const string& separator, const Iter& begin, const Iter& end)
{
string result;
for (Iter i=begin; i != end; ++i) {
result += *i;
if (i != (end - 1)) {
result += separator;
}
}
return result;
}
template<class StringContainer>
StringContainer split(const string& str, const string& separator)
{
StringContainer result;
size_t start, end;
start = 0;
while ((end = str.find(separator, start)) != str.npos) {
result.push_back(str.substr(start, end - start));
start = end + separator.length();
}
result.push_back(str.substr(start));
return result;
}
Code: Alles auswählen
cout << join("-", array.begin(), array.end()) << endl;
list<string> splitted = split<list<string> >("foo<->bar<->frobnitz", "<->");
Zu den Template-Fehlermeldungen hier ein nettes Beispiel, welches mir beim Schreiben der Beispiele untergekommen ist:
Code: Alles auswählen
test.cpp: In function `int main()':
test.cpp:55: error: could not convert `std::find [with _InputIterator =
__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string,
std::allocator<std::string> > >, _Tp = char[4]]((&array)->std::vector<_Tp,
_Alloc>::begin [with _Tp = std::string, _Alloc = std::allocator<std::string>](),
(&array)->std::vector<_Tp, _Alloc>::end [with _Tp = std::string, _Alloc =
std::allocator<std::string>](), ((const char (&)[4])"bar"))' to `bool'
Nochmal zum PHP-Python Spickzettel: Bei dem `substr()` Beispiel sollte auf jeden Fall ein Satz erklären, dass die beiden Argumente bei PHP Start und Länge, bei Python aber Start und Ende darstellen. Aus den angegebenen Beispielen wird das nämlich nicht unbedingt klar.