2 Fragen zu Listen in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Melody
User
Beiträge: 18
Registriert: Donnerstag 29. August 2013, 15:22

Hallo an alle,

ich hoffe, ich stelle die Frage auch im richtigen Forum :).
Ich habe zwei allgemeinere Fragen zu Listen in Python (bin Anfänger):

Ich habe zum Beispiel eine Liste die wieder herum zwei Listen enthält:
Liste=[[a,b,c], [d,e,f]]
Mit dem Befehl Liste[0] kann man ja zum Beispiel auf das Element [a,b,c] zugreifen. Gibt es nun auch eine Möglichkeit oder einen Befehl, mit dem man zum Beispiel auf das Element a der Unterliste direkt zugreifen kann?

Nun meine zweite Frage.
Ich habe verschiedene Messreihen, aus denen ich Minima auslesen muss, ein Beispiel ist:
-1
-2
4
5
22.5
23
23.55
22.34
-2.11
-3.22
-3.0
-4.5
-5.0
22.5
23.45
25.05
24.00
20
10
5
-3.0
-2.3
-2.0

Ich wollte dies durch die Festlegung einer unteren Grenze (z.B. -1) und durch einen Vergleich mit dem nachfolgenden Element machen. Leider ist es mir nicht möglich in einer Schleife oder der Kopie der Liste auf das nachfolgende Element zuzugreifen. Bei der Schleife erscheint immer die Fehlermeldung "IndexError: list index out of range" und beim Kopieren der Liste ignoriert Python den Befehl. Was mache ich falsch?

Die Code-Beispiele sind:

Mit einer Schleife:

Liste2=[]
for i in range(len(Liste1)):
if Liste1<-1 and Liste1<Liste1[i+1]:
Liste2.append(Liste1)

print Liste2


Mit einer Kopie der Liste:

Liste2=[x for x in Liste1 if x<-1 and x<(x+1)]

print Liste2


Vielen Dank schon mal für eure Hilfe, ich bin langsam schon am Verzweifeln ;).
BlackJack

@Melody: ``Liste[0]`` ist kein Befehl sondern ein Ausdruck. Und zwar wird per Indexoperator zugegriffen. Bei einer Liste bedeutet das, man übergibt den Index des gewünschten Elements und bekommt dann als Ergebnis das Element an dem Index. Wenn das eine Liste ist, wie in diesem Fall, kann man auf das Ergebnis natürlich wieder den Indexoperator anwenden um ein Element aus dieser Liste zu erhalten. Mehr als zwei oder drei Ebenen tief sollte man das allerdings nicht machen. Nicht weil die Programmiersprache das nicht könnte, sondern weil die meisten menschlichen Leser bei zu tief verschachtelten Datenstrukturen irgendwann den Überblick verlieren was welcher Index in welcher Tiefe eigentlich bezogen auf die Daten *bedeutet*.

Zur zweiten Frage: Du kennst die `min()`-Funktion!?

Beim `IndexError` ist der Fehler das Du auch beim *letzen* Element auf das nächste Element zugreifen willst, was natürlich nicht geht, denn da ist ja kein Element mehr nach dem Letzten. ;-)

Bei der „list comprehension” überlege mal worauf die beiden Teilbedingungen bei dem ``if``-Teil operieren. Insbesondere welche Teilbedingung unsinnig ist, weil sie *immer* wahr ist.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Melody hat geschrieben:Ich habe zum Beispiel eine Liste die wieder herum zwei Listen enthält:
Liste=[[a,b,c], [d,e,f]]
Mit dem Befehl Liste[0] kann man ja zum Beispiel auf das Element [a,b,c] zugreifen. Gibt es nun auch eine Möglichkeit oder einen Befehl, mit dem man zum Beispiel auf das Element a der Unterliste direkt zugreifen kann?

Code: Alles auswählen

>>> data = [['A', 'B', 'C'], ['D', 'E']]
>>> first_list = data[0]
>>> print first_list[1]
B
>>> print data[0][1]
B
Melody
User
Beiträge: 18
Registriert: Donnerstag 29. August 2013, 15:22

Vielen Dank an euch zwei!
Die zwei Antworten haben mir sehr weitergeholfen, ich habe jetzt das Programm zum Finden der Maxima/Minima schreiben können :).
Melody
User
Beiträge: 18
Registriert: Donnerstag 29. August 2013, 15:22

Jetzt hat sich gerade noch eine neue Frage aufgetan:

Der Zugriff auf die Unterlisten funktioniert jetzt soweit, aber wie kann ich in einer Schleife darauf zugreifen?

Das Code-Beispiel:

Code: Alles auswählen

for k in range(len(Liste)):
    for i in range(k+1):
        print Liste[k][i]
funktioniert leider nicht, als Fehlermeldung erscheint "TypeError: object of type 'int' has no len()".

Vielen Dank bereits für eure Hilfe!
Zuletzt geändert von Anonymous am Donnerstag 29. August 2013, 18:27, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@Melody: Laut Fehlermeldung hast Du eine Zahl an den Namen `Liste` gebunden. Was ziemlich verwirrend ist. Hast ja selber gedacht an `Liste` sein eine Liste gebunden.

Auf diese Weise sollte man aber sowieso nicht auf Listen zugreifen. Wenn Du über die Elemente in einer Liste iterieren möchtest, dann kannst Du das *direkt* machen, ohne einen Umweg über Indizes:

Code: Alles auswählen

for sub_list in a_list:
    for item in sub_list:
        print item
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Melody hat geschrieben: Ich wollte dies durch die Festlegung einer unteren Grenze (z.B. -1) und durch einen Vergleich mit dem nachfolgenden Element machen. Leider ist es mir nicht möglich in einer Schleife oder der Kopie der Liste auf das nachfolgende Element zuzugreifen.
Auch wenn sich die Frage erübrigt hat, nur mal der Vollständigkeit halber. ``izip_longest`` aus dem ``itertools``-Modul kann hier helfen:

Code: Alles auswählen

# l ist eine Liste mit Deinen Beispielwerten
list(izip_longest(l, l[1:], fillvalue=0))
> [(-1.0, -2.0),
 (-2.0, 4.0),
 (4.0, 5.0),
 (5.0, 22.5),
 (22.5, 23.0),
 (23.0, 23.55),
 (23.55, 22.34),
 (22.34, -2.11),
 (-2.11, -3.22),
 (-3.22, -3.0),
 (-3.0, -4.5),
 (-4.5, -5.0),
 (-5.0, 22.5),
 (22.5, 23.45),
 (23.45, 25.05),
 (25.05, 24.0),
 (24.0, 20.0),
 (20.0, 10.0),
 (10.0, 5.0),
 (5.0, -3.0),
 (-3.0, -2.3),
 (-2.3, -2.0),
 (-2.0, 0)]
Damit kann man auch Deine Bedingung von oben formulieren:

Code: Alles auswählen

[a for a, b in izip_longest(l, l[1:], fillvalue=0) if a < b and a < -1]
> [-2.0, -3.22, -5.0, -3.0, -2.3, -2.0]
Ein Glück hatte sich das mit ``min`` ja schnell geklärt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

oder:

Code: Alles auswählen

>>> reduce(lambda a,b:a[:a and (a[-1]>-1 or a[-1]>b) and -1 or None]+[b],x,[])
[-2.0, -3.22, -5.0, -3.0, -2.3, -2.0]
Melody
User
Beiträge: 18
Registriert: Donnerstag 29. August 2013, 15:22

BlackJack hat geschrieben:@Melody: Laut Fehlermeldung hast Du eine Zahl an den Namen `Liste` gebunden. Was ziemlich verwirrend ist. Hast ja selber gedacht an `Liste` sein eine Liste gebunden.

Auf diese Weise sollte man aber sowieso nicht auf Listen zugreifen. Wenn Du über die Elemente in einer Liste iterieren möchtest, dann kannst Du das *direkt* machen, ohne einen Umweg über Indizes:

Code: Alles auswählen

for sub_list in a_list:
    for item in sub_list:
        print item
Danke für die Hilfe. Aber leider stehe ich gerade etwas auf der Leitung. Ich habe probiert, das Beispiel für eine Liste umzusetzen, aber die Schleife läuft nicht durch. Ich muss doch eigentlich nur für a eine Liste definieren, oder?

An alle anderen:
Vielen Dank für eure Hilfe, der Lerneffekt ist wirklich groß.

Edit:
Die Frage hat sich geklärt, dafür ist eine neue aufgetaucht ;). Das obere Beispiel funktioniert für folgende Listenart zum Beispiel nicht:

Code: Alles auswählen

a_list=[[1, 2, 3], 4]
Es erscheint die Fehlermeldung "int object is not iterable". Gibt es eine andere Möglichkeit, um die Elemente so einer Liste ausgeben zu lassen, deren Elemente nicht nur aus Teillisten bestehen?
BlackJack

@Melody: Da würde ich mich als erstes fragen warum die Liste überhaupt so aussieht. Die Elemente in einer Liste sollten vom gleichen Typ beziehungsweise mindestens vom gleichen „duck type” sein. Sonst bekommt man nämlich genau solche Probleme, dass man nicht alle Elemente gleich behandeln kann, sondern den Quelltext durch Sonderfälle verkomplizieren muss. Wenn die Liste so aussehen würde: ``[[1, 2, 3], [4]]`` hätte man das Problem nicht.
Melody
User
Beiträge: 18
Registriert: Donnerstag 29. August 2013, 15:22

Ja das stimmt, dann werde ich darauf achten, Danke!
Antworten