Neu bei Python, aber eine Frage habe ich schon

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.
gorzka
User
Beiträge: 7
Registriert: Freitag 2. Januar 2009, 20:17

Neu bei Python, aber eine Frage habe ich schon

Beitragvon gorzka » Freitag 2. Januar 2009, 20:30

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
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Freitag 2. Januar 2009, 20:33

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)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 2. Januar 2009, 21:01

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Freitag 2. Januar 2009, 21:02

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]
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Beitragvon hendrikS » Freitag 2. Januar 2009, 21:03

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
Zuletzt geändert von hendrikS am Freitag 2. Januar 2009, 21:08, insgesamt 1-mal geändert.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Freitag 2. Januar 2009, 21:04

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)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 2. Januar 2009, 21:15

Birne94 hat geschrieben:Index 2 ist schon richtig imo.


Klar, sonst würde er ja das Skript selbst verarbeiten ... :oops:
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Beitragvon hendrikS » Freitag 2. Januar 2009, 21:59

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.
BlackJack

Beitragvon BlackJack » Freitag 2. Januar 2009, 22:44

@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.
gorzka
User
Beiträge: 7
Registriert: Freitag 2. Januar 2009, 20:17

Beitragvon gorzka » Samstag 3. Januar 2009, 11:44

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
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Samstag 3. Januar 2009, 12:00

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
gorzka
User
Beiträge: 7
Registriert: Freitag 2. Januar 2009, 20:17

Beitragvon gorzka » Samstag 3. Januar 2009, 18:19

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.
BlackJack

Beitragvon BlackJack » Samstag 3. Januar 2009, 18:43

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.
gorzka
User
Beiträge: 7
Registriert: Freitag 2. Januar 2009, 20:17

Beitragvon gorzka » Samstag 3. Januar 2009, 19:18

Danke, werde ich dann mal machen.

Gibt es vielleicht so etwas wie selfhtml für Python?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Beitragvon str1442 » Samstag 3. Januar 2009, 19:19

docs.python.org

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder