Dateipfad + Dateiname zusammenfügen

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
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Hallo Leute,
wenn ich versuche einen Dateipfad mit einem Dateinamen zusammenzufügen, erscheinen immer 2 Backslashes statt nur einem...

Code: Alles auswählen

A = []

fobj = open("Bilder.txt", "r")
for line in fobj: 
    s = "Testbilder\JPEGBild\\" + line
    zuordnung = s.split("\n")
    A.append(zuordnung[0]) 
fobj.close()

print(A)
Die Ausgabe ist: ['Testbilder\\JPEGBild\\Picture1.txt', 'Testbilder\\JPEGBild\\Picture2.txt', 'Testbilder\\JPEGBild\\Picture3.txt']
Statt wie erwartet: ['Testbilder\JPEGBild\Picture1.txt', 'Testbilder\JPEGBild\Picture2.txt', 'Testbilder\JPEGBild\Picture3.txt']

Und wenn ich mit

Code: Alles auswählen

print(A[0])
ausgebe, kommt: Testbilder\JPEGBild\Picture1.txt
wie es auch sein sollte....

Woran liegt das?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Weil du versuchst zwei Zeichenketten zu verbinden nicht zwei Pfade.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@barisoezcan: Du hast die falsche Erwartung bei der Ausgabe. Bei der Umwandlung einer Liste in eine Zeichenkette werden die einzelnen Elemente mit `repr()` umgewandelt und nicht mit `str()`, ganz einfach damit man sieht was *tatsächlich* in den Zeichenketten enthalten ist. Da der Backslash in Zeichenketten eine besondere Bedeutung hat, muss er escaped werden, damit man einfach Backslashes von solchen unterscheiden kann, die mit dem folgenden Zeichen etwas anderes bedeuten als ein Backslash gefolgt von einem Zeichen.

Zum zusammen setzen von Pfaden sollte man die `os.path.join()`-Funktion verwenden statt ``+``.

`fobj` könnte man `lines` nennen. Das wäre deutlicher.

Statt umständlich mit `split()` das Zeilenende *nachher* zu entfernen, könnte man das gleich am Anfang und mit der `strip()`- oder `rstrip()`-Methode machen.

Wenn man die Datei zusammen mit der ``with``-Anweisung verwendet, braucht man sie nicht explizit schliessen und kann sich auf der anderen Seite sicher sein, dass sie geschlossen wird, auch wenn zwischen öffnen und schliessen zum Beispiel eine Ausnahme auftritt.

Edit:

Code: Alles auswählen

import os

IMAGE_BASE_PATH = r'Testbilder\JPEGBild'


def main():
    with open('Bilder.txt', 'r') as lines:
        image_paths = [
            os.path.join(IMAGE_BASE_PATH, line.rstrip()) for line in lines
        ]
    print(image_paths)


if __name__ == '__main__':
    main()
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Vielen Dank! :D

Hab es nun zuende programmiert.
Es klappt, aber gibt es vllt noch Verbesserungsvorschläge?

Code: Alles auswählen

from PIL import Image
import os

IMAGE_BASE_PATH = r'Testbilder\Strand und Strasse\Strand\\'

with open('Bilder.txt', 'r') as lines:
    image_paths = [
        os.path.join(IMAGE_BASE_PATH, line.rstrip()) for line in lines
    ]


red_pixels = []
data = []

for image_path in image_paths:
    img = Image.open(image_path)
    pixel = img.getdata()
    for j in range(len(pixel)):
        red_pixels.append(pixel[j][0])
    data.append(red_pixels)
    red_pixels = []
Die Listenelemente von "data" enthalten die roten Pixelwerte von den einzelnen Bildern.
Also:
"data[0]" enthält alle roten Pixelwerte vom 1.Bild.
"data[1]" enthält alle roten Pixelwerte vom 2.Bild.
usw...
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Bitte kein for-range-len:

Code: Alles auswählen

red_pixels = [pix[0] for pix in pixel]
Der Doppel-\\ in IMAGE_BASE_PATH ist wirklich einer, weil raw-String.
BlackJack

@barisoezcan: `red_pixels` wird an den falschen Stellen an eine leere Liste gebunden. Wenn man es richtig macht, dann braucht man das nur *einmal* innerhalb der Schleife machen und nicht vor *und* innerhalb der Schleife.

Der Backslash beziehungsweise die Backslashes am Ende von `IMAGE_BASE_PATH` sind überflüssig. Genau dafür sorgt `os.path.join()` ja schon.

Den Rotanteil in einer Python-Schleife zu ermitteln ist ineffizient. Man kann PIL direkt nach einer Sequenz nur mit den roten Pixelwerten fragen. Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
import os
from PIL import Image

IMAGE_BASE_PATH = r'Testbilder\Strand und Strasse\Strand'


def main():
    with open('Bilder.txt', 'r') as lines:
        image_paths = [
            os.path.join(IMAGE_BASE_PATH, line.rstrip()) for line in lines
        ]
    data = list()
    for image_path in image_paths:
        image = Image.open(image_path)
        data.append(image.getdata(image.getbands().index('R')))


if __name__ == '__main__':
    main()
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Es funktioniert wunderbar...
Vielen Dank :D
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Kann man das "with open" auch für's in ne Datei schreiben verwenden?
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

probier's aus!
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Klappt :oops:
Antworten