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)
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).
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)
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
peut être:
for x in range(N):
lines.append(f.readline())
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
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.
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]]
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) ]