Seite 1 von 1

Problem mit Array

Verfasst: Samstag 5. Dezember 2009, 17:17
von Accredo
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.

Verfasst: Samstag 5. Dezember 2009, 18:37
von 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.

Verfasst: Samstag 5. Dezember 2009, 18:58
von HWK
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

Verfasst: Samstag 5. Dezember 2009, 19:37
von 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()

Verfasst: Samstag 5. Dezember 2009, 20:33
von Accredo
@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.