Seite 1 von 1
Slicing
Verfasst: Donnerstag 29. Januar 2004, 15:01
von Martin
Hallo!
Ich habe gerade erst mit Python angefangen, und es geht aschon ganz gut, einige elemetare Dinge bereiten mir allerdings noch Probleme.
Im Moment ist es das Slicing von Sequenzen.
Konkret habe ich eine Funktion, die sechs Werte in einem tupel zurückgibt, von denen ich allerdings nur vier brauche.
Mein erster Versuch wäre gewesen:
(a,b,c,d) = foo()[0,1,3,4]
Das geht offensichtlich nicht.
Nach Konsultation der Python Language Reference habe ich das probiert:
(a,b,c,d) = foo()[0:2,3:5]
Geht aber auch nicht

obwohl ich eigentlich glaube, dass das syntaktisch korrekt ist. (?)
Wahrscheinlich stehe ich gerade ziemlich auf der Leitung, wie mache ich das also?
Wie würde ich das machen, wenn ich ein beliebiges Tupel als Indices verwenden will, als zB so:
t = (0,1,3,4)
(a,b,c,d) = foo()[t]
Re: Slicing
Verfasst: Donnerstag 29. Januar 2004, 15:43
von Milan
Martin hat geschrieben:Nach Konsultation der Python Language Reference habe ich das probiert:
(a,b,c,d) = foo()[0:2,3:5]
Geht aber auch nicht

obwohl ich eigentlich glaube, dass das syntaktisch korrekt ist. (?)
Leider nicht. Slicing ist das erstellen einer Teilliste, wo du einfach angibst von wo bin wo. Der 3. Parameter ist die Schrittfolge. Das lässt sich in deinem Fall also nicht so realisieren, du musst dir die Liste selber basteln zusammenbasteln: [foo()[0:2],foo()[3:5]]
Verfasst: Donnerstag 29. Januar 2004, 16:02
von Dookie
Hi Martin,
ich hab mal was probiert:
Code: Alles auswählen
>>> liste = [101,102,103,104,105,106]
>>> a, b, c, d = [liste[x] for x in xrange(len(liste)) if x in (0,1,3,4)]
>>> print a, b, c, d
102 102 104 105
Ansonst müsstest Du halt eine Neue Klasse von Liste ableiten, die über
__getattr__ ein Tuple entgegennimmt un die zu den im Tuple enthaltenen Werte aus der Liste als Liste zurückgibt.
Gruß
Dookie
Re: Slicing
Verfasst: Donnerstag 29. Januar 2004, 16:04
von Voges
Hallo!
Mein Senf noch dazu:
Martin hat geschrieben:(a,b,c,d) = foo()[0:2,3:5]
Geht aber auch nicht

obwohl ich eigentlich glaube, dass das syntaktisch korrekt ist. (?)
Python kann sowas nicht (eigentlich verwunderlich, wenn ich so darüber nachdenke). Ein Komma im []-Operator ist auf jeden Fall nicht erlaubt. Perl z.B. hat sowas:
Code: Alles auswählen
sub foo {
return "a","b","c","d","e","f","g","h","i";
}
print ((foo())[0..1,3..4]);
Hab' ich hin und wieder genutzt, aber bei Python eigentlich noch nie wirklich vermisst.
Martin hat geschrieben:Wie würde ich das machen, wenn ich ein beliebiges Tupel als Indices verwenden will, als zB so:
t = (0,1,3,4)
(a,b,c,d) = foo()[t]
Da fällt mir auf die Schnelle nur sowas ein:
t = (0,1,3,4)
a,b,c,d = [c for i,c in enumerate(foo()) if i in t]
So schön ist das aber auch nicht.
Jan
Verfasst: Donnerstag 29. Januar 2004, 16:11
von Dookie
Als ichs abgeschickt hatte, dachte ich das geht doch einfacher:
Dookie
Verfasst: Donnerstag 29. Januar 2004, 16:16
von Dookie
jetzt noch mit deinem foo und dem tuple in t
schaut doch nett aus
Dookie
Verfasst: Donnerstag 29. Januar 2004, 16:23
von Voges
Hallo!
Sowas würde ich nie nicht nimmer machen, selbst wenn ich (aktuell) genau wüsste, was in foo() passiert. Irgendwann wird foo() mal geändert (ein globaler Zähler z.B. aktualisiert) und schon hat man einen häßlichen Seiteneffekt.
Jan
Verfasst: Donnerstag 29. Januar 2004, 16:52
von Dookie
Hi Voges,
warum ?
foo() liefert eine Liste und wird wie bei einer Zuweisung an eine Variable nur einmal aufgerufen. Objekte sind, von Funktionen abgesehen anonym. Also ob du die Referenz auf die Liste die foo() liefert erst in einer Variablen speicherst oder gleich verwendest bleibt egal.
Gruß
Dookie
Verfasst: Donnerstag 29. Januar 2004, 16:59
von Martin
Danke für die vielen Antworten
Allerdings:
Hier steht eigentlich, dass Konstrukte wie [1:2,3:4] erlaubt sein müssten. (siehe slicelist )
sehr seltsam...
Dann werde ich halt den klassischen Weg gehen:
t = foo()
a,b = t[0:2]
c,d = t[3:5]
(muss eine Angewohnheit aus Perl sein, alles in eine Zeile schreiben zu wollen.

)
Verfasst: Donnerstag 29. Januar 2004, 17:22
von Milan
Dookie hat geschrieben:Hi Voges,
warum ?
foo() liefert eine Liste und wird wie bei einer Zuweisung an eine Variable nur einmal aufgerufen.
FALSCH!
bei dir wird foo exakt 4 mal aufgerufen, und falls foo eben nicht nur eine Liste zurückgibt, sonder noch mehr macht, führt das ganz leicht zu Problemen. Bsp:
Code: Alles auswählen
x=1
def foo():
global x
x+=1
return range(x,x+6,1)
print [foo()[i] for i in (0,1,3,4)]
Alles klar? Also ist Martins letzte Variante wohl die beste.
Verfasst: Donnerstag 29. Januar 2004, 17:35
von Voges
Hallo!
Martin hat geschrieben:Hier steht eigentlich, dass Konstrukte wie [1:2,3:4] erlaubt sein müssten. (siehe slicelist )
Da kommt man schon ins Grübeln
Martin hat geschrieben:(muss eine Angewohnheit aus Perl sein, alles in eine Zeile schreiben zu wollen.

)
Geht auch:
a,b,c,d = t[0:2]+t[3:5]
Jan
Verfasst: Donnerstag 29. Januar 2004, 17:40
von Dookie
@Milan: hmm seltsam stimmt.
Man lernt halt nie aus. Aber wenn ich sowas öfter brauche, bastel ich mir halt eine Klasse.
Code: Alles auswählen
class xslist(list):
def __getitem__(self, xs):
try:
return [self[i] for i in xs]
except:
return super(xslist, self).__getitem__(xs)
Gruß
Dookie
Verfasst: Donnerstag 29. Januar 2004, 19:42
von Voges
Voges hat geschrieben:Hallo!
Martin hat geschrieben:Hier steht eigentlich, dass Konstrukte wie [1:2,3:4] erlaubt sein müssten. (siehe slicelist )
Da kommt man schon ins Grübeln

Ich weiß schon, warum die "Language Reference" den Untertitel "for language lawyers" hat. Zu denen zähle ich mich nun wirklich nicht.
Also: Sequenzen
können diese Slice-List-Syntax unterstützen,
müssen aber nicht. Und die Standard-Sequenzen (Liste,Tuple,String) tun das auch nicht. So einfach ist das

. Laut Google ist wohl Numerical Python[1] das einzige nennenswerte Modul, das eben diese Slice Lists unterstützt (Siehe z.B. [2]).
Jan
[1]
http://sourceforge.net/projects/numpy
[2]
http://tinyurl.com/ytbrx
Verfasst: Donnerstag 29. Januar 2004, 22:33
von Martin
Danke für die Nachforschungen.
Schon irgendwie seltsam, dass man nicht eine beliebige Sequenz als Index verwenden kann, weil das wäre eigentlich das intuitivste

(meiner meinung nach zumindest)
Perl hat da seine Vorteile
