Ich habe ein Skript geschrieben, das Daten aus zwei verschiedenen Dateien liest und entsprechend vorgeht. Als ich das Skript schrieb, hatte ich jedoch den Eindruck, dass die erste Datei, aus der ich lese, nur zwei Zeilen enthält. Leider hat sich dies seitdem geändert.

Mein Code extrahiert die ersten beiden Zeilen und übergibt die Daten an eine andere Funktion, die dann die Berechnung durchläuft, indem sie mehrere andere Funktionen durchläuft.

Im Moment mache ich so etwas:

try:
    file = open(myfile, 'r')
    for line in file:
        if line[0] != '|':
            name = line.strip('\n')
        else:
            data = line.strip('|\n')

Die Datei sieht im Allgemeinen folgendermaßen aus:

Samantha
|j&8ju820kahu9|

Jetzt kann ich leider eine Datei haben, die mehrere Zeilen haben kann, wie folgt:

Andy
|o81kujd0-la88js|
Mathew
|a992kma82nf-x01j4|
Andrew
|01ks83nnz;a82jlad|

Gibt es eine Möglichkeit, zwei Zeilen gleichzeitig aus einer Datei zu extrahieren? Verarbeiten Sie sie und extrahieren Sie dann zwei weitere? Nehmen Sie also die ersten beiden Zeilen, geben Sie sie an Name + Daten weiter, die sie an meine Funktion übergeben, drucken Sie schließlich das, was erforderlich ist, und holen Sie sich dann die neuen zwei Zeilen und so weiter.

Bitte um Rat.

2
Nauman Shahid 17 Apr. 2018 im 22:45

5 Antworten

Beste Antwort

Ja, da der Dateikontext auch ein Iterator ist:

with open(filename, 'r') as f:
    for l1, l2 in zip(f, f):
        # ... do something with l1 and l2

Dies ist der kürzeste und pythonischste Weg afaik.

6
OneRaynyDay 17 Apr. 2018 im 19:56

Sie können die Listenspleißnotation list[<begin>:<end>:<step>] verwenden, um Listenelemente beim Iterieren zu überspringen. Wenn Ihre Datei klein ist, können Sie sie mit readlines() auf einen Schlag in den Speicher lesen.

Betrachten Sie so etwas Verwenden Sie nicht file als Dateihandle. Es beschattet eingebaute file

In [9]: a = my_file.readlines()
In [10]: for i, line in enumerate(a[::2]):
   ...:     data_line = a[i+1]
   ...:     name = line.strip('\n')
   ...:     data = data_line.strip("|\n")
   ...:     print name
   ...:     print data
   ...:
Andy
o81kujd0-la88js
Mathew
Mathew
Andrew
a992kma82nf-x01j4

In [11]:

(Ich persönlich würde so etwas wie ein Regex-Match machen).

-1
Srini 17 Apr. 2018 im 20:05

Eine Lösung für Sie könnte sein:

data = {}
with open(filename) as f:
    for name, value in zip(f, f):
        data[name] = value

Eine Erklärung zur zip -Funktion mit Iteratoren finden Sie in der Dokumentation.

Dies geht auch aus dem Rezept in der itertools-Dokumentation hervor:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)
0
TwistedSim 17 Apr. 2018 im 20:23

Natürlich kannst du.

okay = False
with open(...) as f:
  while True:
    okay = False
    try:
      line_1 = next(f)
      line_2 = next(f)
      okay = True
      # ... do something with the pair of lines
    except StopIteration:
      break;  # End of file.
if not okay:
   complain("The file did not contain an even number of lines")
0
9000 17 Apr. 2018 im 20:07

Versuche dies

from itertools import islice
with open(filename, 'r') as infile:
    current_slice = islice(infile, N)
for line in current_slice:
    print line

Wobei N die Anzahl der Zeilen ist, die Sie verarbeiten möchten, und current_slice ein Generatorobjekt ist, das Ihnen jede Zeile der Datei gibt und in einer Schleife verwendet werden kann. Dies sollte Ihnen zwei Zeilen gleichzeitig geben. Anstatt zu drucken, können Sie Ihre Vorgänge ausführen und dann mit den nächsten beiden Zeilen fortfahren

Eine andere Option ist

from itertools import izip_longest

with open(filename) as f:
     for lines in grouper(f, N, ''):
         for line in lines:
             # process N lines here
-2
AbtPst 17 Apr. 2018 im 20:00