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
Slicing mehrdimensionaler Arrays
Hallo rer und Willkommen im Forum!
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.
MfG EnTeQuAk
Also ich will ja jetzt nichts sagen... aber erklär mir mal bitte, warum du a1 und b1 erwartet hast?rer hat geschrieben: >>>x=[['a0','a1'],['b0','b1']]
>>> x[:][1]
['b0', 'b1']
Code: Alles auswählen
x[:]
Code: Alles auswählen
['a0', 'a1'], ['b0', 'b1']
Also ganz normal dein Ergebnis. Hat nichts mit Design/Implementierungsfehler zu tun. Also freue ich mich nicht auf eine nicht anregende, sinnlose Diskussion.
Vielleicht sind es auch einfach ein paar Denkfehler deinerseits gewesen.
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.
MfG EnTeQuAk
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
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?
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:
Code: Alles auswählen
a = x[:]
a[1]
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?
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
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
Du wirfst hier mit Begriffen um dich. Matrix, Listen, Arrays... Schlag mich tot... aber die haben nicht wirklich viel miteinander zu tun.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
Code: Alles auswählen
>>> l = [['a', 'b'], ['c', 'd']]
>>> (l[:])[1] == l[:][1]
True
Erklär mir mal, was du mit Gradlinigkeit meinst.ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
Beispiele helfen hier besser weiter. Vielleicht können wir dir dann besser helfen.
MfG EnTeQuAk
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Mmh, mal sehen:rer hat geschrieben:ansonsten hat Python eben keine solche Geradlinigkeit in diesem Zusammenhang
Code: Alles auswählen
a = [funktion1, funktion2, funktion3]
a[1](param1, param2)
funktion4(param1, param2)[5]
funktion5(param1, para,3)(param3, param4)
# ...
Code: Alles auswählen
x = [[1, 2], [3, 4]]
x[:][1] # -> [3, 4]
Listen sind keine Matrizen. Punkt.
Das ist aber auch nicht gerade Gradlinig wenn was zurück gegeben wird was nicht in den Listen an entsprechenden Positionen vorhanden ist.rer hat geschrieben:wenn eine solche Syntax im Kern implementiert waere, bei unterschiedlich langen sub-Listen koennte bei Luecken ja None zurueckgegeben werden
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']
Oder nimm Matrixklassen wenn echt Matrizen benötigt werden, aber keine Listen
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?
@zap: was sind Matrix-Klassen? ist das das array-Modul aus der Standard-lib, und kann man damit Spalten slicen?
@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).
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).
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
Danke fuer die Denkanstoesse
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.
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.
Wie man Fragen richtig stellt
Außerdem gibt es eine irrationale.
Wie man Fragen richtig stellt
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
In MatLab funktioniert das halt ein bisschen anders: wenn du eine Matrix A hast,
kannst du so etwas machen:
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...
Code: Alles auswählen
1 2 3
4 5 6
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)
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...
Ah, jetzt hab ich mir das Eingangsbeispiel nochmal angesehen und habs auch kapiert. Danke Rebecca, danke Koffein!
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.
Wie man Fragen richtig stellt
Außerdem gibt es eine irrationale.
Wie man Fragen richtig stellt