Liste aus file - Elemente verändern

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
zucki
User
Beiträge: 2
Registriert: Dienstag 8. Juli 2008, 18:09

Dienstag 8. Juli 2008, 18:27

Hi!

Ich mache grade meine ersten Schritte mit Python und versuche etwa Folgendes:

Code: Alles auswählen

http://firefoxmac.furbism.com/rss_feed.php|||
http://www.forbes.com/leadership/governance/index.xml|||
http://www.forbes.com/ebusiness/index.xml|||
]...]
Diese Liste ist lang, steht in einer Datei, die urls heisst. Da will ich die 3 Striche am Ende löschen.

Also bastle ich mir eine Klasse Textfile:

Code: Alles auswählen

lass textfile:
    ntfiles=0
    
    def __init__(self,fname):
        textfile.ntfiles+=1
        self.name=fname
        self.fh = open(fname)
        self.lines=self.fh.readlines()
        self.nlines=len(self.lines)
        self.nwords=0
        self.wordcount()
    
    def wordcount(self):
        "finds the number of words in the file"
        for l in self.lines:
            w=l.split()
            self.nwords+=len(w)
    
    def grep(self, target):
        "prints out all lines containin target"
        for l in self.lines:
            if l.find(target)>=0:
                print l
Dann definiere ich das Textfile und führe die Methoden aufs Objekt aus:

Code: Alles auswählen

a=textfile('urls')
# print "the number of text files open is", textfile.ntfiles
print "here is some information about them (name, lines, words):"
   
for f in [a]:
    print f.name, f.nlines
    # listenlaenge = f.nlines

# so weit ist das alles klar...
# aber:

for i in range(f.nlines-1):
    one_url=(f.lines[i].split())
    clean_url=
    print clean_url
Das Letzte und natürlich Wichtigste: Wie bekomme ich ich die Strings in der Liste aus Strings quasi in eine Liste aus Chars, sodass ich jeweils die letzten 3 Elemente abschneiden kann?
split() braucht immer einen Separator. Ich habe halt keinen...

Das ist für mich nen Lernbeispiel. Ich kann das sicher ohne Python mit awk auf der Shell machen oder in C++ in 2 Minuten über nen Array.
Allerdings will ich ja Python lernen :)

Hat da wer ne Idee hier?

Gruß,
zucki
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Dienstag 8. Juli 2008, 18:32

Code: Alles auswählen

>>> s = "string|||"
>>> s[:-3]
'string'
Keine Ahnung, warum du da ne Klasse schreibst, das geht in ein paar Zeilen Pythoncode.
Wenn du mit Klassen rumspielen willst, kannst du dir ja auch 'ne geeignetere Aufgabe dafür suchen :)
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 8. Juli 2008, 18:35

Strings haben eine replace-Methode, damit kannst du das machen.

Aber was bitte soll das:

Code: Alles auswählen

for f in [a]: 
    print f.name, f.nlines 
? Dann kannst du auch gleich

Code: Alles auswählen

print a.name, a.nlines 
schreiben.

Außerdem kannst du direkt über Listen iterieren und musst nicht den Umweg über die Indizes gehen. Falls du letztere doch brauchst, gibt es enumerate.

Die Klasse finde ich noch etwas seltsam, ich gehe aber mal davon aus, dass du dich auch darin einarbeiten willst.
zucki
User
Beiträge: 2
Registriert: Dienstag 8. Juli 2008, 18:09

Dienstag 8. Juli 2008, 18:59

Danke für die Tipps ;)

Ich hab Programmieren halt an der Uni gelernt. Da macht man leider alles mit Klassen und OOP. Obwohl es sicher auch anders modellierbar ist. Grad um mal nen bissel Pragmatik reinzukriegen mach ich ja Python.
Wobei ich persönlich finde, dass die Klasse soo seltsam gar nicht is *g*.

Code: Alles auswählen

for i in range(a.nlines-1):
    one_url=a.lines[i]
    one_url=one_url[:-4]
    print "add " + "\"" + one_url + "\""


Ist so ne Art best-Practise. Config files schreiben lassen und so. Jetzt nimmt das Skript jede url und formatiert sie syntaktisch um, sodass ein anderes Programm damit auch was anfangen kann.

Ja... erste Schritte :)

Gruß,
zucki
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Dienstag 8. Juli 2008, 19:12

Und was ist daran jetzt pragmatischer als direkt über das Dateiobjekt zu iterieren und sich einmal Indexerei zu sparen?
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Dienstag 8. Juli 2008, 19:14

Öffne Die Datei, iteriere über jede Zeile und wenn sie den Bedingungen entspricht füg sie einer Liste zu. Wenn du mehr als 15 Zeilen brauchst, hast du imho was falsch gemacht.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Dienstag 8. Juli 2008, 19:21

Keep it simple, stupid!

Man kann auch objektorientiert Arbeiten ohne Klassen zu erstellen.

Und so ginge es auch:

Code: Alles auswählen

text = """\
http://firefoxmac.furbism.com/rss_feed.php|||
http://www.forbes.com/leadership/governance/index.xml|||
http://www.forbes.com/ebusiness/index.xml||| 
""".split()

def iter_strip(iterable):
    for line in iterable:
        yield line.rstrip('|')

for line in iter_strip(text):
    print line
wobei die Funktion natürlich auch wieder überflüssig ist, aber die hab ich zum Besseren Verständnis gelassen.
Die nimmt ein beliebiges Iterable von String und entfernt dort die '|' am Ende.
BlackJack

Dienstag 8. Juli 2008, 19:39

@zucki: Du solltest mal das Tutorial aus der Dokumentation durcharbeiten und PEP8, den "style guide" lesen. Das was Du da machst ist in Python jedenfalls nicht unbedingt "best practise".

Dateien die man öffnet, sollte man auch wieder schliessen. Insbesondere wenn man eine (IMHO unnötige) Referenz darauf behält.

Die Anzahl der Zeilen würde ich nicht als Attribut speichern, weil man damit die Information dupliziert, die man auch mit `len()` vom Attribut `lines` bekäme. Wenn man solche Daten redundant hält, besteht immer die Gefahr, dass sie irgendwann mal "auseinanderlaufen". Wenn es so ein Attribut auf Deinen Objekten geben soll, kann man das auch mit einem Property weiter delegieren. Oder man definiert `Textfile.__len__()`.

Pythonischer, allerdings ungetestet:

Code: Alles auswählen

class Textfile(object):
    def __init__(self, filename):
        self.name = filename
        in_file = open(filename, 'r')
        self.lines = list(in_file)
        in_file.close()
    
    def __iter__(self):
        return iter(self.lines)
    
    def __len__(self):
        return len(self.lines)
    
    def count_words(self):
        return sum(len(line.split()) for line in self)
    
    def grep(self, needle):
        for line in self:
            if needle in line:
                print line


def main():
    urls = Textfile('urls')
    print urls.name, len(urls), urls.count_words()
    for url in urls:
        print 'add "%s"' % url[:-4]


if __name__ == '__main__':
    main()
Antworten