Seite 1 von 2

Neu bei Python, aber eine Frage habe ich schon

Verfasst: Freitag 2. Januar 2009, 20:30
von gorzka
Ich versuche mich gerade in Python einzuarbeiten. Nachdem ich PHP schon einigermaßen beherrsche scheint mir das eine gute Alternative zu anderen Sprachen in der Konsole (Linux zu sein). Die Syntax ist ja ähnlich, aber ebend nur ähnlich.

Nun schon mal meine erste Frage. Ich versuche mivch an folgendem:

Code: Alles auswählen

#!/usr/bin/python

import sys
import string

# Dateiname ermitteln
dateiname = sys.argv[2]  # Skriptname steht in sys.argv[0]
parameter = sys.argv[1]  # Argrument steht in sys.argv[1]
# Argument ermitteln


if parameter == '-b':
 # open and read file
 try:
  datei = open(dateiname, 'r')
  zeilen = datei.readlines()
  datei.close()
 except IOError:
  print dateiname, "ist nicht lesbar"
  sys.exit(2)

 # sortieren der Zeilen und ersetzen
 zeilen.sort()
 zeilen = zeilen.replace("\t", ",")
 zeilen = zeilen.replace(" ", ",")
Wenn ich das richtig gemacht habe öffnet er eine Datei nach einem bestimmten Parameter (klappt)

Er liest diese Datei in eine Variable (klappt)

Die Variable wird sortiert (klappt)

Nun soll er aber in dieser Variabel alle Tabulatoren und Leerzeichen dur ein Komma ersetzen. Und das Klappt ebend nicht. Ich bekomme da folgende Meldung:

Traceback (most recent call last):
File "./virsort.py", line 24, in <module>
zeilen = zeilen.replace("\t", ",")
AttributeError: 'list' object has no attribute 'replace'

Er liest ja alle Zeilen einer Datei in eine Variable. Darin sind nun Tabulatoren und Leerzeichen enthalten. die ich gerne duch ein Komma ersetzen möchte.

Für eine Anfängerhilfe bin ich sehr dankbar

Ach so, Allen noch ein gesundes neues Jahr und viel Gesundheit usw.

Thomas

Verfasst: Freitag 2. Januar 2009, 20:33
von Birne94

Code: Alles auswählen

zeilen.sort()
zeilen = "$$".join(zeilen).replace("\t", ",").split("$$")
zeilen = "$$".join(zeilen).replace(" ", ",").split("$$")
nen bissl umständlich, aber...

EDIT:

Code: Alles auswählen

zeilen = map(lambda s: s.replace("\t",","), zeilen)
zeilen = map(lambda s: s.replace(" ",","), zeilen)

Verfasst: Freitag 2. Januar 2009, 21:01
von numerix
Hallo gorzka,

willkommen im Forum.

Ein paar Anmerkungen und eine (andere) Lösung für dein Problem:

In Zeile 8 muss der Index 0 lauten, nicht 2.
Für das Auslesen der Parameter sollte man auch ein Exception-Handling einbauen, damit das Programm nicht gleich terminiert, wenn man den Parameter vergessen hat ...
Das string Modul brauchst du nicht zu importieren. Es gibt zwar eins, aber das verwendest du gar nicht.
Das Ersetzen durch die Kommas könnte man so lösen (das Sortieren hast du dann auch gleich mit drin):

Code: Alles auswählen

zeilen = sorted(zeile.replace("\t",",").replace(" ",",") for zeile in zeilen)
Das ersetzt deine Zeilen 24-26.

Verfasst: Freitag 2. Januar 2009, 21:02
von birkenfeld
Spätestens wenn man als Argument für map() ein lambda verwenden muss, wird eine eine List comprehension schöner:

Code: Alles auswählen

zeilen = [z.replace('\t', ',') for z in zeilen]

Verfasst: Freitag 2. Januar 2009, 21:03
von hendrikS
Birne94 hat geschrieben:

Code: Alles auswählen

zeilen.sort()
zeilen = "$$".join(zeilen).replace("\t", ",").split("$$")
zeilen = "$$".join(zeilen).replace(" ", ",").split("$$")
nen bissl umständlich, aber...

Code: Alles auswählen

zeilen = map(lambda s: s.replace("\t",","), zeilen)
zeilen = map(lambda s: s.replace(" ",","), zeilen)
Gute Lösungen. Beduerfen aber vielleicht einer kleinen Erläuterung fuer jemanden, der Python beginnt:
1.) replace kann man nur auf Strings anwenden nicht auf listen (die von readlines() zurueckgegeben wird)
2.) Lösung 1 verbindet alle Zeilen mit einem "$$" zu einem String und trennt sie anschliessend wieder am "$$". Das setzt voraus, dass die Datei vorher keine "$$" enthält. Sonst wird Anzahl der Zeilen durch das Splitten am Ende grösser.
3.) Also ist Lösung 2 eigentlich besser. Kann man auch gut mit einer List Comprehension machen. EDIT: Siehe Lösung von Birkenfeld

Verfasst: Freitag 2. Januar 2009, 21:04
von Birne94
numerix hat geschrieben:Hallo gorzka,

willkommen im Forum.

Ein paar Anmerkungen und eine (andere) Lösung für dein Problem:

In Zeile 8 muss der Index 0 lauten, nicht 2.
Für das Auslesen der Parameter sollte man auch ein Exception-Handling einbauen, damit das Programm nicht gleich terminiert, wenn man den Parameter vergessen hat ...
Das string Modul brauchst du nicht zu importieren. Es gibt zwar eins, aber das verwendest du gar nicht.
Das Ersetzen durch die Kommas könnte man so lösen (das Sortieren hast du dann auch gleich mit drin):

Code: Alles auswählen

zeilen = sorted(zeile.replace("\t",",").replace(" ",",") for zeile in zeilen)
Das ersetzt deine Zeilen 24-26.
Index 2 ist schon richtig imo.
Imo will er einen übergebenen Pfad auslesen (Quelltext des ausführenden Programmes ändern oO)

Verfasst: Freitag 2. Januar 2009, 21:15
von numerix
Birne94 hat geschrieben:Index 2 ist schon richtig imo.


Klar, sonst würde er ja das Skript selbst verarbeiten ... :oops:

Verfasst: Freitag 2. Januar 2009, 21:59
von hendrikS
Viele Wege fuehren nach Rom. Auch in Python.

Das sollte auch gehen. Habs kurz laufen lassen.

Code: Alles auswählen

zeilen=sorted(datei.read().replace("\t",",").replace(" ",",").split('\n'))
EDIT
Kurze Erläuterung: read() gibt direkt einen String zurueck, auf den replace() angewendet werden kann. Danach Trennung am "new line" und Sortierung.

Verfasst: Freitag 2. Januar 2009, 22:44
von BlackJack
@gorzka: Vielleicht noch etwas zur Terminologie: Du liest die Datei nicht in eine Variable, sondern in eine Liste, und Du sortierst auch keine Variable, sondern wieder die Liste.

Die Fehlermeldung sagt Dir, das Listen keine `replace()`-Methode kennen.

Verfasst: Samstag 3. Januar 2009, 11:44
von gorzka
Danke erst mal für die vielen Antworten. Nun kann ich mir das alles mal zu Gemüte führen und so ein bischen besser einarbeiten

Verfasst: Samstag 3. Januar 2009, 12:00
von sma
hendrikS hat geschrieben:

Code: Alles auswählen

zeilen=sorted(datei.read().replace("\t",",").replace(" ",",").split('\n'))
Wenn möglich, würde ich Dateien immer als Strom und nie als einen kompletten String lesen. Obiges Programm benötigt bei großen Dateien mindestens doppelt so viel Hauptspeicher für jeden Schritt.

Da man sortieren will, landet letztlich doch die ganze Datei im Hauptspeicher, aber eben nur 1x und schon zerteilt in Strings. Ich würde außerdem einen regulären Ausdruck benutzen, um das zweimalige Ersetzen und damit neu Anlegen der Strings zu vermeiden. Das mag zwar etwas langsamer sein, ist aber netter zur automatischen Speicherverwaltung.

Code: Alles auswählen

with open("...") as lines:
lines = sorted(re.sub("[\t ]", ",", line) for line in lines)
Stefan

Verfasst: Samstag 3. Januar 2009, 18:19
von gorzka
Ich habe die Methode von hendrikS genommen und es funktioniert super.

Nun habe ich folgendes Problem:
Am Zeilen ende steht jetzt eine" ,1". Diese soll durch die aktuelle Zeilennummer ersetzt werden.

Ich benötige nicht unbedingt fertige Lösungen, aber in der Doku stehen die Befehle sehr unübersichtlich da. Da finde ich die Doku von PHP besser.
Vielleicht gibt es ja auch andere Seiten mit der Syntax oder zum einlesen.

Verfasst: Samstag 3. Januar 2009, 18:43
von BlackJack
Die PHP-Doku enthält viele Beispiele, und es ist nicht unüblich, dass man sich von Problem zu Problem hangelt, in dem man dort abschreibt und anpasst. Das mag am Anfang schnellere Erfolge erzielen, ist aber IMHO auch ein Grund warum viele PHP-Programmierer auf einem ziemlich erbärmlichen Niveau verharren und aufgeschmissen sind, sobald sie für irgendetwas kein Beispiel mehr finden.

Arbeite das Tutorial in der Python-Dokumentation durch und mach Dich mit den Grunddatentypen und ihren Methoden vertraut.

Vielleicht solltest Du die Daten auch nicht als Liste von Zeilen, sondern als Liste von Listen mit Feldern modellieren. Die inneren Listen lassen sich mit der `split()`-Methode von Zeichenketten einfach erstellen, das letzte Element hat den Index -1 und für die Nummern, schau Dir mal die `enumerate()`-Funktion an. Zusammensetzen mit Kommata geht dann mit der `join()`-Methode auf Zeichenketten.

Verfasst: Samstag 3. Januar 2009, 19:18
von gorzka
Danke, werde ich dann mal machen.

Gibt es vielleicht so etwas wie selfhtml für Python?

Verfasst: Samstag 3. Januar 2009, 19:19
von str1442
docs.python.org

Verfasst: Samstag 3. Januar 2009, 19:34
von gorzka
Für einen englisch Laien vielleicht auch in Deutsch?

Verfasst: Samstag 3. Januar 2009, 19:38
von DasIch
Eine deutsche Übersetzung der Dokus gibt es soweit ich weiß nicht aber man hat es da ja nicht mit komplexen Texten zu tun.

Verfasst: Samstag 3. Januar 2009, 19:41
von derdon
Oder, um es mit den Worten von Leonidas zu sagen (Quelle: http://www.python-forum.de/post-121130.html#121130):
Leonidas hat geschrieben:Die Hardwarevorraussetungen an Programmierer sind "Kann feststellen ob Computer an ist und wenn dies nicht der Fall ist diesen einschalten" und "Kann Englisch". Letzteres ist dank all der Übersetungsfunktionen (Google Translate, Babelfish) und Online-Wörterbücher (LEO und etliche weitere) einfacher als je zuvor, aber eine Investition an brauchbares Englisch zahlt sich mit der Zeit doppelt und dreifach aus.

Verfasst: Samstag 3. Januar 2009, 19:58
von hendrikS
Hallo gorzka,

erst mal muß ich für die Python docu eine Lanze brechen. Ich finde sie super. Wie man mit Strings und Listen arbeitet ist dort schön erklärt.
String Slicing ist in Python bis auf eine Sache wunderbar gemacht. In Php entspricht das, glaube ich, der Funktion substr().

folgender Code als Anhaltspunkt:

Code: Alles auswählen

z="ABCDE,1"
n=45
z=z[:-2]+str(n)
print z

Verfasst: Samstag 3. Januar 2009, 20:00
von gorzka
Dann werde ich mal alles probieren. Nur durch einfache Praxis lernt man ja bekanntlich. Beispiel. "Hello World" und dann immer weiter.

Gutes Forum