web-dev-qa-db-fra.com

Comment lire fichier N lignes à la fois en Python?

Je dois lire un gros fichier en lisant au plus N lignes à la fois, jusqu'à EOF. Quel est le moyen le plus efficace de le faire en Python? Quelque chose comme:

with open(filename, 'r') as infile:
    while not EOF:
        lines = [get next N lines]
        process(lines)
25
madprogrammer

Une solution serait une compréhension de liste et l’opérateur de tranche:

with open(filename, 'r') as infile:
    lines = [line for line in infile][:N]

Après cette lines est tuple de lignes. Cependant, le fichier complet serait chargé en mémoire. Si vous ne le souhaitez pas (c'est-à-dire si le fichier peut être très volumineux), il existe une autre solution utilisant une expression de générateur et islice du paquet itertools:

from itertools import islice
with open(filename, 'r') as infile:
    lines_gen = islice(infile, N)

lines_gen est un objet générateur, qui vous donne chaque ligne du fichier et peut être utilisé dans une boucle comme celle-ci:

for line in lines_gen:
    print line

Les deux solutions vous donnent jusqu'à N lignes (ou moins, si le fichier n'en a pas beaucoup).

30
Martin Thurau

Ce code fonctionnera avec n'importe quel nombre de lignes dans le fichier et avec n'importe quelle N. Si vous avez 1100 lines dans le fichier et N = 200, vous aurez 5 fois le temps de traiter des morceaux de 200 lignes et une fois avec 100 lignes.

with open(filename, 'r') as infile:
    lines = []
    for line in infile:
        lines.append(line)
        if len(lines) >= N:
            process(lines)
            lines = []
    if len(lines) > 0:
        process(lines)
7
Anatolij

Je pense que vous devriez utiliser des morceaux au lieu de spécifier le nombre de lignes à lire. Cela rend votre code plus robuste et générique. Même si les lignes sont grandes, l'utilisation de chunk ne téléchargera que la quantité de données attribuée en mémoire.

Reportez-vous à this link

1
Konstant

peut être: 

for x in range(N):
  lines.append(f.readline())
1
yurib

Je cherchais une réponse à la même question, mais je n'aimais pas vraiment tout ce qui était proposé plus tôt, alors j'ai fini par écrire cette chose légèrement moche qui fait exactement ce que je voulais sans utiliser d'étranges bibliothèques.

def test(filename, N):
    with open(filename, 'r') as infile:
        lines = []
        for line in infile:
            line = line.strip()
            if len(lines) < N-1:
                lines.append(line)
            else:
                lines.append(line)
                res = lines
                lines = []
            yield res
        else:
            if len(lines) != 0:
                yield lines
0
Haromn

J'avais besoin de lire n lignes à la fois à partir de fichiers pour des fichiers extrêmement volumineux (~ 1 To) et d'écrire un package simple pour le faire. Si vous pip install bigread, vous pouvez faire:

from bigread import Reader

stream = Reader(file='large.txt', block_size=10) 
for i in stream:
  print(i)

block_size est le nombre de lignes à lire à la fois. 

0
duhaime

Si vous pouvez lire l'intégralité du fichier à l'avance; 

infile = open(filename, 'r').readlines()
my_block = [line.strip() for line in infile[:N]]
cur_pos = 0
while my_block:
    print (my_block)
    cur_pos +=1
    my_block = [line.strip() for line in infile[cur_pos*N:(cur_pos +1)*N]]
0
ChrisEisenhart

Vous devrez peut-être faire quelque chose d'aussi simple que:

lines = [infile.readline() for _ in range(N)]

Mise à jour après commentaires:

lines = [line for line in [infile.readline() for _ in range(N)] if len(line) ]
0
quamrana