Seite 1 von 1
Slicing mehrdimensionaler Arrays
Verfasst: Montag 21. Mai 2007, 09:08
von rer
Hallo,
Ich beschaeftige mich seit ca. 1 Monat mit python, habe bisher sehr viel in Perl gemacht und muss doch feststellen, das python einige Implementierungs- wenn nicht gar Designfehler hat.
Beispiel mehrdimensionale Arrays:Spaltenweises extrahieren aus Matrix
>>>x=[['a0','a1'],['b0','b1']]
>>> x[:][1]
['b0', 'b1']

Das ist doch wohl ein schlechter Witz! Ich wuerde da a1,b1 erwarten, und das auch vor dem Hintergrund wo sich python doch immer so ruehmt eine 'ueberraschungsfreie' Sprache zu sein und ausserdem im Gegensatz zu Perl ein komfortables handlen von 2+D-Arrays zu ermoeglichen
wuensche eine anregende Diskussion
Re: Slicing mehrdimensionaler Arrays
Verfasst: Montag 21. Mai 2007, 09:24
von EnTeQuAk
Hallo rer und Willkommen im Forum!
rer hat geschrieben:
>>>x=[['a0','a1'],['b0','b1']]
>>> x[:][1]
['b0', 'b1']
Also ich will ja jetzt nichts sagen... aber erklär mir mal bitte, warum du a1 und b1 erwartet hast?
Damit erhälst du sozusagen
Und hier greifst du wieder *ganz normal* auf die erste Stelle ([0]) und die zweite stelle ([1]) zu.
Also ganz normal dein Ergebnis. Hat nichts mit Design/Implementierungsfehler zu tun. Also freue ich mich nicht auf eine nicht anregende, sinnlose Diskussion.
Ich beschaeftige mich seit ca. 1 Monat mit python, habe bisher sehr viel in Perl gemacht und muss doch feststellen, das python einige Implementierungs- wenn nicht gar Designfehler hat.
Vielleicht sind es auch einfach ein paar Denkfehler deinerseits gewesen.
MfG EnTeQuAk
Verfasst: Montag 21. Mai 2007, 09:40
von Rebecca
Ich glaube, das was rer erwartet, kommt aus MatLab.
rer, dein x ist weder ein Array noch eine Matrix, sondern eine Liste von Objekten. Nichts weiter. Und da macht das von Ente erklaerte Verhalten Sinn. Du musst die Eckigen Klammern von Links nach Rechs lesen, und [:] tut nichts weiter, als eine Kopie eine Liste zu erzeugen, und auf diese Liste wendest du dann [1] an. Also in langform:
Hier sieht man doch, dass das Verhalten ganz natuerlich ist, kein Designfehler.
Die Funktionsweise, die du dir vorstellst, ist schon sehr speziell, denn das die Items einer Liste alle wieder aus (gleichlangen) Listen bestehen, kommt ja eher selten vor. Das von dier erwartete Verhalten macht nur in dem Spezialfall Sinn, dass du die Liste als Matrix verwenden willst. Fuer mathematische Verwendungen waere vielleicht numpy/scipy eher was fuer dich?
Verfasst: Montag 21. Mai 2007, 10:52
von rer
Hallo EnTeQuAk,
das verstehe ich schon wenn man das als Verkettung von Ausdruecken versteht, nur wuerde ich mir das von dir geschilderte Ergebnis eher von einem Konstrukt wie (X[:])[1] versprechen. Im Sinne einer logischen, konsequenten und vollstaendigen Array/Listen/Matrixzugriffssyntax wuerde ich mir aber trotzdem mein erwartetes Ergebnis versprechen, ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
@rebecca: numpy kenne ich und nutze es auch, trotzdem wuerde ich wuenschen, wenn eine solche Syntax im Kern implementiert waere, bei unterschiedlich langen sub-Listen koennte bei Luecken ja None zurueckgegeben werden
Verfasst: Montag 21. Mai 2007, 11:05
von EnTeQuAk
Hallo EnTeQuAk,
das verstehe ich schon wenn man das als Verkettung von Ausdruecken versteht, nur wuerde ich mir das von dir geschilderte Ergebnis eher von einem Konstrukt wie (X[:])[1] versprechen. Im Sinne einer logischen, konsequenten und vollstaendigen Array/Listen/Matrixzugriffssyntax wuerde ich mir aber trotzdem mein erwartetes Ergebnis versprechen, ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
Du wirfst hier mit Begriffen um dich. Matrix, Listen, Arrays... Schlag mich tot... aber die haben nicht wirklich viel miteinander zu tun.
Code: Alles auswählen
>>> l = [['a', 'b'], ['c', 'd']]
>>> (l[:])[1] == l[:][1]
True
Das ist ja auch das feine an Python. Man muss kaum maskieren(hieß das so) und mit Klammern arbeiten. Es fasst das meißt selber sehr intellegent zusammen.
ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
Erklär mir mal, was du mit
Gradlinigkeit meinst.
Beispiele helfen hier besser weiter. Vielleicht können wir dir dann besser helfen.
MfG EnTeQuAk
Verfasst: Montag 21. Mai 2007, 11:35
von Rebecca
rer hat geschrieben:ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
Mmh, mal sehen:
Code: Alles auswählen
a = [funktion1, funktion2, funktion3]
a[1](param1, param2)
funktion4(param1, param2)[5]
funktion5(param1, para,3)(param3, param4)
# ...
In diesem Zusammenhang istalles andere als
eine Ausnahme von der Regel.
Listen sind keine Matrizen. Punkt.
Verfasst: Montag 21. Mai 2007, 12:10
von Zap
rer hat geschrieben:wenn eine solche Syntax im Kern implementiert waere, bei unterschiedlich langen sub-Listen koennte bei Luecken ja None zurueckgegeben werden
Das ist aber auch nicht gerade
Gradlinig wenn was zurück gegeben wird was nicht in den Listen an entsprechenden Positionen vorhanden ist.
Eine Matrix sollte im gesamten initialisiert sein a x b
Wenn du eben die Elemente haben willst, wie oben beschrieben, nutze doch
die line-comprehension:
Code: Alles auswählen
>>> x = [["a0","a1"],["b0","b1"]]
>>> [ e[1] for e in x ]
['a1', 'b1']
Birgt allerdings die Gefahr das bei ungleichen Listen der Indexzugriff ins leere greift und dir ne Exception um die Ohren haut.
Oder nimm Matrixklassen wenn echt Matrizen benötigt werden, aber keine Listen
Verfasst: Montag 21. Mai 2007, 13:08
von rer
Es ist ja nicht so das ich mein Problem nicht mit Paketen wie numpy nicht elegant loesen koennte, insofern ist die Diskussion nur akademisch, sollte sie uebrigens von Anfang an auch nur sein. Was mich nur wundert, ist weil die meisten Programmiersprachen ja den Zugriff auf mehrdimensionle Arrays, oder nennen wir es Tabellenn oder Zeilen/Spalten-Strukturen, damit keine Begriffsverwirrung aufkommt, in der Form x[a] oä bieten, was ja schliesslich auch die weitaus haeufigste Form der Datenanordnung ist (Tabellen,Grids,Spreadsheets,Datenbanken). Python bietet das auf den ersten Blick auch, aber nur auf den ersten und auch nicht durchgaengig, weil das eben als referenzierte Listen implementiert ist. Ausserdem wird in fast jedem Python-Tutorial suggeriert, dass Python mehrdimensionale Arrays unterstuetzt (im Gegensatz zu Perl), was ja wohl definitiv nicht stimmt (zumindest builtin). Ich wollte halt nur nicht fuer solche Alltagsaufgaben gleich ein dickes Numpy-modul mit mir rumschleppen, und dachte, das das auch einfacher geht.
@zap: was sind Matrix-Klassen? ist das das array-Modul aus der Standard-lib, und kann man damit Spalten slicen?
Verfasst: Montag 21. Mai 2007, 13:33
von BlackJack
@rer: Also das mit dem Geradlinig verstehe ich auch nicht. ``obj[a]`` bedeutet so wie es jetzt implementiert ist *immer* hole das Objekt an Index `a` von Objekt `obj` und von *dem* Objekt dann das Objekt an Index `b`.
Du möchtest nun also das nicht so ``(obj[a])`` geklammert wird, sondern so ``obj([a])``. Dafür hätte ich jetzt gerne mal eine semantische Beschreibung was bei Indexoperator auf Indexoperator angewendet passieren soll. Und dass bitte nicht für so spezielle Objekte wie Matrizen sondern für *allgemeine* Objekte `obj`, so dass Deine Beschreibung auch für verschachtelte Abbildungen, Listen oder sonstwas gilt und trotzdem noch so einfach und geradeheraus beschrieben und angewendet werden kann, wie das jetzt der Fall ist.
Ach und Dir ist klar, dass ``obj[a]`` im Grunde nur syntaktischer Zucker für ``obj.__getitem__(s).__getitem(b)`` ist und dass man diese Methode bei eigenen Objekten ganz einfach überschreiben kann, um das Verhalten zu implementieren!? Wenn Du Deine Semantik erklärst, dann beschreibe bitte auch gleich wie man Dein Verhalten genauso einfach selbst implementieren und Anpassen kann.
Von welchen anderen Programmiersprachen redest Du da? Die meisten gebräuchlichen haben kein Slicing wie von Dir gewünscht. C, C#, C++, Java, Pascal haben das alle nicht. Eher "Spezialsprachen" wie Matlab oder IDL. Oder auch Python mit Objekten, die so etwas implementieren.
Zweidimensionale "Arrays" mit ``obj[a]`` kann man mit verschachtelten Listen realisieren. Im Gegensatz zu Perl ist das einfacher weil man sich nicht explizit mit Referenzen befassen muss. Und diese verschachtelten Listen funktionieren im Grunde nicht anders als mehrdimensionale Arrays in C#, Java und Co. Auf ganze Zeilen kann man recht einfach zugreifen, Werte einer Spalte muss man in einer Schleife ansprechen.
So häufig ist aber so eine Datenstruktur auch nicht, jedenfalls nicht wenn man OOP programmiert. Eine DB-Tabelle würde dann eher in einer Liste von Objekten, die aus den Daten einer Zeile gebildet werden, bestehen oder aus einer Abbildung (Schlüssel, Objekt aus Zeile).
Verfasst: Montag 21. Mai 2007, 18:35
von rer
so wie die Python-(Pseudo)Matritzen als verschachtelte Listen implementiert sind, und nicht als eigene Datentypen mit eigenen Operatoren, scheint es tatsaechlich etwas schwierig zu sein eine solche Zugriffssyntax zu implementieren, ohne den Komfort der normalen Listsyntax zu opfern. Ich werd mal versuchen eine Klasse zu entwickeln, die durch ueberladen von __getitem ueber list-comprehensives die Spalten ausspuckt
Danke fuer die Denkanstoesse
Verfasst: Dienstag 22. Mai 2007, 08:15
von N317V
Vielleicht wirkt ja mein Morgenkaffee noch nicht, aber ich muss jetzt tatsächlich mal zugeben, dass ich das Problem immernoch nicht verstanden hab. Ich finde das Verhalten im Beispiel ebenfalls vollkommen überraschungsfrei.
Verfasst: Dienstag 22. Mai 2007, 08:49
von Rebecca
In MatLab funktioniert das halt ein bisschen anders: wenn du eine Matrix A hast,
kannst du so etwas machen:
Code: Alles auswählen
A(1, 2) -> 2
A(1, 2:3) -> 2, 3
A(:, 1) -> erste Spalte
A(:, 1:2) -> Teilmatrix (erste und zweite Spalte)
Bei MatLab hat man eben keine Verkettung wie bei [][], sondern der erste Parameter beim Aufruf gibt den Bereich fuer die Reihenindices an, der zweite Paramter den Bereich fuer die Spaltenindices.
Das macht fuer Matrizen in einem numerischen Tool ja auch Sinn, ist halt was komplett anderes als verschachtelte Listen in einer allgemeinen Programmiersprache. Matlab traegt die Matrizen ja auch schon im Namen...

Verfasst: Dienstag 22. Mai 2007, 09:08
von N317V
Ah, jetzt hab ich mir das Eingangsbeispiel nochmal angesehen und habs auch kapiert.

Danke Rebecca, danke Koffein!
