Arrays und for-Schleifen

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
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

Hallo,

ich habe bisher C, C++ und Java programmiert. Pythin ist neu und ich finde einfach keine Erklärung zu diesen Konstrukten:

value = [line.strip() for line in file.readlines()]

Das gibt es noch in andern Ausführungen. Ich weiß, was das Resultat ist, aber kann mir jemand erklären, wie und was das macht?

Ich will z.B. eine Datei zeilenweise auslesen. Wenn ich die Datei öffne, kann ich mit arr = file.readlines() die einzelnen zeilen in einer Liste speichern. Jedoch sind noch die abschließenden '\n' mit im Array. Das obige Beispiel schneidet den zeilenumbruch ab. ich habe es mit einer for-Schleife probiert (was nicht funktionierte) und habe dann den obigen Code gefunden.

Code: Alles auswählen

file = open("C:/tmp/" + fname)   
arr = file.readlines()
for x in arr:    
    arr2.append(x.strip('\n'))
file.close()
In file sind die einzelnen Zeilen mit den Zeielnumbrüchen gespeichert. Wie kann ich in der Schleife ein neues Array anlegen und mit den neuen bearbeiteten Strings initialisieren.

Vielen Dank für euer Hilfe.

MfG
kreuzritter
deets

Das Stichwort heißt Listcomprehension.
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

vielen dank! :)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Code: Alles auswählen

a = [f(x) for x in y if g(x)]
ist die Kurzform für

Code: Alles auswählen

a = []
for x in y:
    if g(x):
        a.append(f(x))
Dabei ist der Teil mit "if" optional.
Stefan
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

kreuzritter hat geschrieben:

Code: Alles auswählen

file = open("C:/tmp/" + fname)   
arr = file.readlines()
for x in arr:    
    arr2.append(x.strip('\n'))
file.close()
In file sind die einzelnen Zeilen mit den Zeielnumbrüchen gespeichert. Wie kann ich in der Schleife ein neues Array anlegen und mit den neuen bearbeiteten Strings initialisieren.
Böse Falle. Dein file überschreibt das eingebaute file.

Dann schauen wir uns den Rest mal an. Dateipfade sollte man mit os.path.join zusammensetzen und für das open bietet sich der Einsatz des Context Managers an der in diesem Fall dafür sorgt, dass die Datei am Ende automatisch geschlossen wird.

Code: Alles auswählen

with open(os.path.join('C:/tmp', fname)) as in_file:
    arr = in_file.readlines()
    for x in arr:    
        arr2.append(x.strip('\n'))
Jetzt schauen wir uns das an was du Array nennst und was eine Liste ist. Besagte Liste müsste übrigens erst einmal angelegt werden bevor Daten hinzugefügt werden können.

Es ist jetzt noch etwas unelegant erst mit readlines alles einzulesen um dann alle Inhalte um das Zeilenende bereinigt in eine neue Liste zu packen. Wir lesen die Datei daher einfach zeilenweise aus und verarbeiten sie.

Code: Alles auswählen

data = []
with open(os.path.join('C:/tmp', fname)) as in_file:
    for line in in_file:    
        data.append(line.strip('\n'))
Man könnte hier eventuell auch mit einem Generator arbeiten.

Code: Alles auswählen

data = []
with open(os.path.join('C:/tmp', fname)) as in_file:
    for line in (line.strip('\n') for line in in_file):
        data.append(line)
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

Danke schon einmal für die zahlreichen Antworten.

Ich habe folgendes:

Ich habe eine Array mit z.B. 10 Elementen.
Ich möchte jetzt ein neues Array erstellen, das z.B. die Stellen 2-5 aus dem Array beinhaltet.
Also:

Gesamtarray
zahlen = [1,2,3,4,5,6,7,8,9,10]

Neues Array:
nzahlen = [3,4,5,6]

Im Moment mache ich das wie folgt:

Code: Alles auswählen

 nzahlen= []  
  for x in range(2, 6, 1):
    nzahalen.append(zahlen[x])
Kann man das auch mit einer ListComprehension machen? Ich weiß nicht genau, wie man das schachteln muss, um es zu verkürzen.

Vielen DAnk :D
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Dafür reicht Slicing vollkommen aus, eine LC wäre an der Stelle vollkommen überdimensioniert:

Code: Alles auswählen

>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(1, 11)[2:6]
[3, 4, 5, 6]
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

Das war ja nur ein Beispiel.
Was ist, wenn ich in dem ersten Array Strings habe?
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Funktioniert ebenfalls. Willkommen zu Ducktyping.
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

python ist echt gewöhnungsbedürftig :P

also slicing angucken...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und sich endlich merken, dass es Listen sind und keine Arrays ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

EyDu hat geschrieben:Und sich endlich merken, dass es Listen sind und keine Arrays ;-)
+1 :D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
kreuzritter
User
Beiträge: 6
Registriert: Donnerstag 21. Juni 2012, 17:59

alles klar ;)
BlackJack

Wobei es in Java auch keinen Unterschied für den Aufruf von `subList()` macht welchen Typ die Elemente von der `List` haben. Python hat halt bloss Syntax für so einen Methodenaufruf. Und in Python wird bei Listen tatsächlich eine Liste erstellt und kein Objekt das nur eine Sicht auf ein Listenobjekt liefert. (Das ist aber nicht garantiert, sondern hängt vom Datentyp ab. `numpy.array`\s liefert in der Regel Sichten beim „slicen”.)

Was bei ``obj[i:j]`` hinter den Kulissen passiert ist ``obj.__getslice__(i, j)`` beziehungsweise ``obj.__getitem__(slice(i, j))``.
Antworten