Frage

Ich habe einige Daten, die ich in einer Liste gespeichert haben, und wenn ich die Liste auszudrucken ich sehe wie folgt vor:

.
.
.
007 A000000 Y
007 B000000  5
007 C010100  1
007 C020100 ACORN FUND
007 C030100 N
007 C010200  2
007 C020200 ACORN INTERNATIONAL
007 C030200 N
007 C010300  3
007 C020300 ACORN USA
007 C030300 N
007 C010400  4
.
.
.

Die Punkte vor und nach der Sequenz darstellen, dass es andere Daten, die ähnlich strukturiert ist, aber möglicherweise oder möglicherweise nicht nicht Teil dieses siebten Punktes (007) sein. wenn der erste Wert im siebten Artikel ist ‚007 A000000 Y‘ dann will ich ein Wörterbuch Auflistung einiger der Datenelemente erstellen. Ich kann dies tun und haben so mit nur läuft durch alle Elemente in meiner Liste und vergleichen ihre Werte zu einigen Testwerte für die Variablen erfolgen. Zum Beispiel kann eine Zeile Code wie:

if dataLine.find('007 B')==0:
    numberOfSeries=int(dataLine.split()[2])

Was ich will, obwohl zu tun ist,

if dataLine.find(''007 A000000 Y')==0:
    READ THE NEXT LINE RIGHT HERE

Im Moment bin ich mit durch die gesamte Liste für jeden Zyklus wiederholen

Ich mag die Verarbeitung verkürzen, weil ich über 60K-Dateien, die zwischen 500 bis 5.000 Linien in jeweils.

Ich habe darüber nachgedacht, einen weiteren Verweis auf die Liste erstellen und die Datenleitungen bis dataLine.find ( ‚‘ 007 A000000 Y ') == 0 zu zählen. Aber das scheint nicht, wie es die eleganteste Lösung ist.

War es hilfreich?

Lösung 5

Ok-während ich googeln, um sicherzustellen, hatte ich meine Grundlagen abgedeckt ich auf eine Lösung kam:

Ich finde, dass ich in Listen und Wörterbücher selbst denken vergessen, obwohl ich sie nutzen. Python hat einige leistungsstarke Werkzeuge mit diesen Typen zu arbeiten, um Ihre Fähigkeit zu beschleunigen, sie zu manipulieren.
Ich brauche eine Scheibe, so dass die Scheibe Referenzen durch leicht erhalten werden

beginPosit = tempans.index('007 A000000 Y')
endPosit = min([i for i, item in enumerate(tempans) if '008 ' in item])

wo tempans ist die Datenliste Ich kann jetzt schreiben

for line in tempans[beginPosit:endPosit]:
    process each line

Ich glaube, ich meine eigene Frage beantwortet. Ich lernte viel von den anderen Antworten und schätzen sie, aber ich denke, das ist das, was ich brauchte,

Okay, ich werde weiter meine Antwort bearbeiten. Ich habe hier viel gelernt, aber einige von diesem Zeug ist mir über den Kopf immer noch, und ich möchte einige Code geschrieben bekommen, während ich mehr über dieses fantastische Werkzeug lerne.

from itertools import takewhile
beginPosit = tempans.index('007 A000000 Y')
new=takewhile(lambda x: '007 ' in x, tempans[beginPosit:])

Dies basiert auf einer früheren Antwort auf eine ähnliche Frage und Steven Huwig die Antwort

Andere Tipps

Sie können itertools.groupby() zu segmentieren Ihre Sequenz in mehrere Untersequenzen verwenden.

import itertools

for key, subseq in itertools.groupby(tempans, lambda s: s.partition(' ')[0]):
    if key == '007':
    for dataLine in subseq:
        if dataLine.startswith('007 B'):
        numberOfSeries = int(dataLine.split()[2])

itertools.dropwhile() würde auch funktionieren, wenn Sie wirklich wollen einfach nur zu dieser Linie suchen nach oben,

list(itertools.dropwhile(lambda s: s != '007 A000000 Y', tempans))
['007 A000000 Y',
 '007 B000000  5',
 '007 C010100  1',
 '007 C020100 ACORN FUND',
 '007 C030100 N',
 '007 C010200  2',
 '007 C020200 ACORN INTERNATIONAL',
 '007 C030200 N',
 '007 C010300  3',
 '007 C020300 ACORN USA',
 '007 C030300 N',
 '007 C010400  4',
 '.',
 '.',
 '.',
 '']

Sie können die Daten in ein Wörterbuch lesen. Vorausgesetzt, dass Sie aus einer Datei-ähnliches Objekt infile lesen:

from collections import defaultdict
data = defaultdict(list)
for line in infile:
    elements = line.strip().split()
    data[elements[0]].append(tuple(elements[1:]))

Nun, wenn Sie die Zeile nach ‚007 A000000 Y‘ lesen möchten, können Sie tun, so wie:

# find the index of ('A000000', 'Y')
idx = data['007'].index(('A000000', 'Y'))
# get the next line
print data['007'][idx+1]

Die einzige Schwierigkeit mit allen Daten in einem Wörterbuch ist, dass ein wirklich großes Wörterbuch lästig werden kann. (Es ist, was wir die "Big Ole Matrix" Ansatz zu nennen pflegte.)

Eine Lösung dieses Problems ist ein Index im Wörterbuch, die Schaffung einer Abbildung von Key-> Offset, mit dem tell Verfahren zu konstruieren, um die Datei-Offset-Wert zu erhalten. Dann können Sie auf die Zeile verweisen erneut mit der seek Methode zu suchen.

Sie sagten, Sie wollen, dies zu tun:

if dataLine.find(''007 A000000 Y')==0:
    READ THE NEXT LINE RIGHT HERE

Vermutlich ist dies in einer „für Datenleitung in Daten“ Schleife.

Alternativ können Sie einen Iterator verwenden, sondern direkt in einer for-Schleife:

>>> i = iter(data)
>>> while i.next() != '007 A000000 Y': pass  # find your starting line
>>> i.next()  # read the next line
'007 B000000  5'

Sie erwähnen auch 60K-Dateien mit zu verarbeiten. Sind sie alle in ähnlicher Weise formatiert? Sie müssen sie anders verarbeitet werden? Wenn sie alle die gleiche Art und Weise verarbeitet werden können, könnten Sie halten sie zusammen in einem einzigen Durchflussverkettungs:

def gfind( directory, pattern="*" ):
    for name in fnmatch.filter( os.listdir( directory ), pattern ):
        yield os.path.join( directory, name )

def gopen( names ):
    for name in names:
        yield open(name, 'rb')

def gcat( files ):
    for file in files:
        for line in file:
            yield line

data = gcat( gopen( gfind( 'C:\datafiles', '*.dat' ) ) )

Auf diese Weise können Sie gemächlich alle Ihre Dateien in einem einzigen Iterator verarbeiten. Nicht sicher, ob das Ihre aktuelle Situation hilft, aber ich dachte, es erwähnenswert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top