335 votes

Comment puis-je lire des fichiers texte volumineux en Python, ligne par ligne, sans les charger en mémoire ?

J'ai besoin de lire un gros fichier, ligne par ligne. Disons que ce fichier a plus de 5 Go et que j'ai besoin de lire chaque ligne, mais je ne veux évidemment pas utiliser la fonction readlines() car cela va créer une très grande liste dans la mémoire.

Comment le code ci-dessous fonctionnera-t-il dans ce cas ? Est-ce que xreadlines lui-même en lisant un par un dans la mémoire ? L'expression du générateur est-elle nécessaire ?

f = (line for line in open("log.txt").xreadlines())  # how much is loaded in memory?

f.next()  

De plus, que puis-je faire pour lire ceci dans l'ordre inverse, comme le Linux tail commande ?

J'ai trouvé :

http://code.google.com/p/pytailer/

y

" python head, tail et backward lire par lignes d'un fichier texte "

Les deux ont très bien fonctionné !

0 votes

Et que puis-je faire pour lire cela depuis la queue ? ligne par ligne, en commençant par la dernière ligne.

0 votes

Ceci devrait être une question séparée

1 votes

448voto

gnibbler Points 103484

J'ai fourni cette réponse car celle de Keith, bien que succincte, ne clôt pas le dossier. explicitement

with open("log.txt") as infile:
    for line in infile:
        do_something_with(line)

50 votes

La question reste la suivante : "for line in infile" chargera mes 5GB de lignes dans la mémoire ? et, comment puis-je lire depuis la queue ?

109 votes

@rochacbruno, il ne lit qu'une ligne à la fois. Lorsque la ligne suivante est lue, la précédente sera collectée, à moins que vous n'ayez stocké une référence à celle-ci ailleurs.

2 votes

@rochacbruno, Lire les lignes dans l'ordre inverse n'est pas aussi facile à faire efficacement malheureusement. En général, vous voudriez lire à partir de la fin du fichier en morceaux de taille raisonnable (kilo-octets à méga-octets disons) et les séparer sur les caractères de nouvelle ligne (ou quel que soit le caractère de fin de ligne sur votre plate-forme).

81voto

Keith Points 13800

Il suffit d'utiliser l'objet fichier comme un itérateur.

for line in open("log.txt"):
    do_something_with(line)

L'utilisation du gestionnaire de contexte dans les versions récentes de Python est encore meilleure.

with open("log.txt") as fileobject:
    for line in fileobject:
        do_something_with(line)

Cela fermera aussi automatiquement le fichier.

4 votes

Cela ne charge pas le fichier entier dans la mémoire ?

0 votes

Ne devriez-vous pas fermer le fichier après la boucle dans le 1er exemple ?

1 votes

@maciejwww oui, mais je ne l'ai pas fait pour que ça ressemble plus à l'exemple du PO. Le deuxième exemple utilise le with est un "gestionnaire de contexte" qui ferme automatiquement l'objet du fichier.

22voto

Mikola Points 5586

Il est préférable d'utiliser un itérateur à la place. Pertinent : http://docs.python.org/library/fileinput.html

Dans la documentation :

import fileinput
for line in fileinput.input("filename"):
    process(line)

Cela évitera de copier tout le fichier en mémoire en une seule fois.

0 votes

Bien que la documentation indique que l'extrait est un "usage typique", son utilisation n'appelle pas la fonction close() de l'objet retourné FileInput lorsque la boucle se termine. J'éviterais donc de l'utiliser de cette façon. Dans Python 3.2, ils ont finalement fait en sorte que fileinput compatible avec le protocole du gestionnaire de contexte qui résout ce problème (mais le code ne serait toujours pas écrit de la manière indiquée).

21voto

jyoti das Points 96

Essayez ceci, s'il vous plaît :

with open('filename','r',buffering=100000) as f:
    for line in f:
        print line

19voto

PTBNL Points 2344

Une approche de la vieille école :

fh = open(file_name, 'rt')
line = fh.readline()
while line:
    # do stuff with line
    line = fh.readline()
fh.close()

2 votes

Petite remarque : pour la sécurité des exceptions, il est recommandé d'utiliser l'instruction 'with', dans votre cas "with open(filename, 'rt') as fh :".

23 votes

@prokher : Oui, mais j'ai appelé ça "old school".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X