Problem mit Array

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
Accredo
User
Beiträge: 10
Registriert: Mittwoch 21. Oktober 2009, 20:34

Hallo,
ich bin noch neu in der Pythonprogrammierung und versuche gerade eine Ausgabedatei zu bearbeiten.Allerding hab ich damit schwierigkeiten :-(.Ich hoffe mir kann jemand helfen.

Meine eingelesene Datei sieht so aus:



Sets included in the consensus tree:

100.00
28. peter
29. lars
40. steffi
31. marco

100.00
39. otto
40. steffi

Sets NOT included in consensus tree:

Mein Programm so:

Code: Alles auswählen

#fileName =raw_input("Enter filename or path to filename: ")
f = open ("4.txt","r")
s = f.read()
f.close()

ausgabe = s.split("Sets NOT included in consensus tree:")[0].split("Sets included in the consensus tree:")[1].split("\n\n")
ausgabe1 = [x for x in ausgabe if x.replace(' ', '') != '']
#Hier wird das eingelesene Textdokument an den wichtigen Stellen gesplittet
#Die Ausgabe sieht so aus:['100.00\n  28. peter\n  29. lars\n  40. steffi\n  31. marco', '100.00\n  39. otto\n  40. steffi']


array = []
for i in range (0,len(ausgabe1)):
 
    array += [ausgabe1[i].split("\n")[1:]]

print array   
#hier werden die einzelnen Blöcke in arrays gepackt und die erste zeile abgespalten da diese nicht gebraucht wird
#die Ausgabe sieht so aus:[['  28. peter', '  29. lars', '  40. steffi', '  31. marco'], ['  39. otto', '  40. steffi']]

for i in range (0,len(ausgabe1)):
    for j in range (0,len(ausgabe1)):
        fnd=array[i][j].find(". ")
#außerdem wird auch die jeweilige Zahl vor den namen nicht benötigt,deshalb spalte ich nach dem Punkt und der Leerzeile
        
fnd1=[]
for i in range (0,len (array)):
    for j in range (0,len(array[i])):
            fnd1 += [array[i][j][fnd+2:]]
print fnd1
#hier hab ich nun versucht die ausgabe ohne die Zahl mit den Punkt dahinter wieder in einzelne Arrays zu bekommen
#die Ausgabe sieht aber so aus:['peter', 'lars', 'steffi', 'marco', 'otto', 'steffi']
Ich will allerdings gerne diese Ausgabe haben:
[['peter', 'lars', 'steffi', 'marco'], ['otto', 'steffi']]

Über jede Hilfe wär ich dankbar.
BlackJack

@Accredo: Vorweg: Die Datenstruktur, die Du verwendest heisst in Python Liste und nicht Array. Du verwendest sie allerdings wie ein Array, was das ganze komplexer macht, als es sein müsste. Man kann in Python über die Elemente einer Liste direkt iterieren und muss das nicht über Indizes machen.

Du gehst IMHO auch "falsch" an die Sache heran. Statt mehrfach über die Daten zu gehen und immer ein klein bisschen daran zu verändern, würde ich eher so viel wie möglich an einem Datum machen und dann erst das nächste anfassen.

Übrigens funktioniert das Programm nur, wenn der '.' bei jedem Datum an der gleichen Stelle steht, denn in der doppelt verschachtelten Schleife bindest Du `fnd` ja immer wieder neu, und nur der allerletzte Wert bleibt dann letztendlich erhalten. Das hätte man also auch als ``fnd = array[-1][-1].find('. ')`` völlig ohne Schleife schreiben können. Ich weiss nicht, ob das wirklich Deine Intention war.

Abkürzungen wie `fnd` und das Anhängen von Nummern an Namen weil einem nichts besseres einfällt tragen nicht unbedingt zur Verständlichkeit des Quelltextes bei.

Du solltest auf jeden Fall noch einmal das Tutorial in der Dokumentation durcharbeiten, dann siehst Du wie man normalerweise Elemente an eine Liste anhängt und ohne die Indizes auskommt. Und hoffentlich auch, wo und warum aus der verschachtelten Liste wieder eine Einfache wird.

Last but not least lohnt hier schon der Einsatz von selbstgeschriebenen Funktionen. Denn da wo die Liste "flach" wird, möchtest Du ja eigentlich die gleiche Operation auf die Elemente von zwei verschiedenen Listen anwenden.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Eine Möglichkeit:

Code: Alles auswählen

import re

regex = re.compile('\d+\. (.+)$')
included_flag = block_flag = False
output = []
with open('test.txt') as infile:
    for line in infile:
        line = line.strip()
        if line == 'Sets included in the consensus tree:':
            included_flag = True
            continue
        elif not included_flag:
            continue
        if line == 'Sets NOT included in consensus tree:':
            break
        match = regex.search(line)
        if match:
            if not block_flag:
                block_flag = True
                output.append([])
            output[-1].append(match.group(1))
        else:
            block_flag = False
print output
Ausgabe:

Code: Alles auswählen

[['peter', 'lars', 'steffi', 'marco'], ['otto', 'steffi']]
MfG
HWK
BlackJack

Eine andere Möglichkeit:

Code: Alles auswählen

#!/urs/bin/env python
# -*- coding: utf-8 -*-
from __future__ import with_statement
import operator
from functools import partial
from itertools import dropwhile, groupby, imap, takewhile


get_first = operator.itemgetter(0)
get_second = operator.itemgetter(1)


def iter_groups(lines, group_start='100.00'):
    
    def stamp():
        i = 0
        for line in lines:
            if line:
                if line == group_start:
                    i += 1
                else:
                    if i == 0:
                        raise ValueError('expected %r but got %r'
                                         % (group_start, line))
                    yield (i, line)
    
    return (imap(get_second, items) for i, items in groupby(stamp(), get_first))


def remove_leading_number(string):
    return string.lstrip('0123456789. \t')


def main():
    is_not_start = partial(operator.ne, 'Sets included in the consensus tree:')
    is_not_end = partial(operator.ne, 'Sets NOT included in consensus tree:')
    
    with open('test.txt') as lines:
        lines = dropwhile(is_not_start, (s.strip() for s in lines))
        lines.next()    # Skip start line.
        lines = takewhile(is_not_end, lines)
        result = [map(remove_leading_number, g) for g in iter_groups(lines)]
        print result


if __name__ == '__main__':
    main()
Accredo
User
Beiträge: 10
Registriert: Mittwoch 21. Oktober 2009, 20:34

@BlackJack und @HWK:
Ich danke euch sehr.
Eure Programme funktionieren.Ich werde mir jetzt mal genau die Quellcodes anschauen damit ich verstehe wie man soetwas genau macht.Find ich echt super.Vielen dank für die Hilfe.
Außerdem schau ich mir auch nochmal das Tutorial dazu an.
Antworten