Comment lire un fichier ligne par ligne dans une liste?


2027

Comment lire chaque ligne d'un fichier en Python et stocker chaque ligne en tant qu'élément dans une liste?

Je veux lire le fichier ligne par ligne et ajouter chaque ligne à la fin de la liste.

Réponses:


2174
with open(filename) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 

206
Ne pas utiliser file.readlines()dans un for-loop, un objet fichier lui-même suffit:lines = [line.rstrip('\n') for line in file]
jfs

88
Dans le cas où vous travaillez avec le Big Data, l'utilisation readlines()n'est pas très efficace car elle peut entraîner MemoryError . Dans ce cas, il est préférable de parcourir le fichier en utilisant for line in f:et en travaillant avec chaque linevariable.
DarkCygnus

7
J'ai vérifié le profil de mémoire de différentes manières données dans les réponses en utilisant la procédure mentionnée ici . L'utilisation de la mémoire est bien meilleure lorsque chaque ligne est lue dans le fichier et traitée, comme suggéré par @DevShark ici . Maintenir toutes les lignes dans un objet de collection n'est pas une bonne idée si la mémoire est une contrainte ou si le fichier est volumineux. Le temps d'exécution est similaire dans les deux approches.
Tirtha R

6
En outre, .rstrip()cela fonctionnera un peu plus rapidement si vous supprimez les espaces des extrémités des lignes.
Gringo Suave

Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta

1002

Voir Entrée et sortie :

with open('filename') as f:
    lines = f.readlines()

ou en supprimant le caractère de nouvelle ligne:

with open('filename') as f:
    lines = [line.rstrip() for line in f]

12
Mieux, utilisez f.read().splitlines(), qui supprime les sauts de ligne
Mark

La deuxième version est-elle for line in open(filename)sécurisée? Autrement dit, le dossier sera-t-il fermé automatiquement?
Becko

2
Il est préférable de lire le fichier une ligne à la fois plutôt que de lire le fichier en entier en une seule fois. Cela ne fonctionne pas bien avec des fichiers d'entrée volumineux. Voir ci-dessous la réponse de robert.
Brad Hein

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]Si j'écris de cette façon, comment puis-je fermer le fichier après la lecture?
Ramisa Anjum Aditi

2
Oui, au point que d'autres font valoir ici, même si ce n'est pas une "meilleure pratique" à utiliser opensans le gestionnaire de contexte (ou une autre manière garantie de le fermer), ce n'est pas vraiment un de ces cas - lorsque l'objet n'a plus de références il sera récupéré et le fichier fermé, ce qui devrait se produire immédiatement en cas d'erreur ou non, lorsque la compréhension de la liste sera terminée.
Aaron Hall

579

C'est plus explicite que nécessaire, mais fait ce que vous voulez.

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)

18
Je préfère cette réponse car elle ne nécessite pas de charger tout le fichier en mémoire (dans ce cas, il est toujours ajouté array, mais il peut y avoir d'autres circonstances). Pour les gros fichiers, cette approche pourrait certainement atténuer les problèmes.
JohannesB

1
L'ajout à un tableau est lent. Je ne peux pas penser à un cas d'utilisation où c'est la meilleure solution.
Elias Strehle

@haccks est-il meilleur car il ne charge pas tout le fichier en mémoire ou y en a-t-il plus?
OrigamiEye

4
Remarque: cette solution ne supprime pas les retours à la ligne.
AMC

1
Cette solution charge tout le fichier en mémoire. Je ne sais pas pourquoi les gens pensent que non.
andrebrait

274

Cela produira un "tableau" de lignes à partir du fichier.

lines = tuple(open(filename, 'r'))

openrenvoie un fichier qui peut être itéré. Lorsque vous parcourez un fichier, vous obtenez les lignes de ce fichier. tuplepeut prendre un itérateur et instancier une instance de tuple pour vous à partir de l'itérateur que vous lui donnez. linesest un tuple créé à partir des lignes du fichier.


31
@MarshallFarrier Essayez lines = open(filename).read().split('\n')plutôt.
Noctis Skytower

16
ferme-t-il le fichier?
Vanuan

5
@Vanuan Puisqu'il n'y a plus de référence au fichier après l'exécution de la ligne, le destructeur doit fermer automatiquement le fichier.
Noctis Skytower

30
@NoctisSkytower Je trouve lines = open(filename).read().splitlines()un peu plus propre, et je crois qu'il gère également mieux les fins de ligne DOS.
jaynp

8
@ mklement0 En supposant un fichier de 1 000 lignes, a listoccupe environ 13,22% plus d'espace qu'un a tuple. Les résultats viennent de from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). La création d'un tupleprend environ 4,17% plus de temps que la création d'un list(avec un écart type de 0,16%). Les résultats proviennent de from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30 exécutions . Ma solution privilégie l'espace à la vitesse lorsque le besoin de mutabilité est inconnu.
Noctis Skytower

194

Si vous voulez l' \ninclus:

with open(fname) as f:
    content = f.readlines()

Si vous ne voulez pas \ninclus:

with open(fname) as f:
    content = f.read().splitlines()

168

Selon les méthodes d'objets de fichier de Python , la façon la plus simple de convertir un fichier texte en un listest:

with open('file.txt') as f:
    my_list = list(f)

Si vous avez juste besoin d'itérer sur les lignes du fichier texte, vous pouvez utiliser:

with open('file.txt') as f:
    for line in f:
       ...

Ancienne réponse:

Utilisation de withet readlines():

with open('file.txt') as f:
    lines = f.readlines()

Si vous ne vous souciez pas de fermer le fichier, ce one-liner fonctionne:

lines = open('file.txt').readlines()

La manière traditionnelle :

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file

150

Vous pouvez simplement faire ce qui suit, comme cela a été suggéré:

with open('/your/path/file') as f:
    my_lines = f.readlines()

Notez que cette approche a 2 inconvénients:

1) Vous stockez toutes les lignes en mémoire. Dans le cas général, c'est une très mauvaise idée. Le fichier peut être très volumineux et vous risquez de manquer de mémoire. Même si ce n'est pas grand, c'est simplement un gaspillage de mémoire.

2) Cela ne permet pas de traiter chaque ligne pendant que vous les lisez. Donc, si vous traitez vos lignes après cela, ce n'est pas efficace (nécessite deux passes plutôt qu'une).

Une meilleure approche pour le cas général serait la suivante:

with open('/your/path/file') as f:
    for line in f:
        process(line)

Où vous définissez votre fonction de processus comme vous le souhaitez. Par exemple:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

(La mise en œuvre de la Supermanclasse est laissée comme un exercice pour vous).

Cela fonctionnera parfaitement pour n'importe quelle taille de fichier et vous parcourez votre fichier en un seul passage. C'est généralement ainsi que fonctionneront les analyseurs génériques.


5
C'était exactement ce dont j'avais besoin - et merci d'avoir expliqué les inconvénients. En tant que débutant en Python, c'est génial de comprendre pourquoi une solution est la solution. À votre santé!
Ephexx

5
Pensez un peu plus à Corey. Voulez-vous vraiment que votre ordinateur lise chaque ligne, sans jamais rien faire avec ces lignes? Vous pouvez certainement réaliser que vous devez toujours les traiter d'une manière ou d'une autre.
DevShark

5
Vous devez toujours faire quelque chose avec les lignes. Cela peut être aussi simple que d'imprimer les lignes ou de les compter. Il n'y a aucune valeur à ce que votre processus lise les lignes en mémoire, mais ne fasse rien avec.
DevShark

2
Vous devez toujours faire quelque chose avec eux. Je pense que l'argument que vous essayez de faire valoir est que vous voudrez peut-être appliquer une fonction à tous en même temps, plutôt qu'une par une. C'est en effet parfois le cas. Mais il est très inefficace d'un point de vue mémoire de le faire, et vous empêche de lire des fichiers si son encombrement est plus grand que votre Ram. C'est pourquoi les analyseurs génériques fonctionnent généralement de la manière que j'ai décrite.
DevShark

2
@PierreOcinom qui est correct. Étant donné que le fichier est ouvert en mode lecture seule, vous ne pouvez pas modifier le fichier d'origine avec le code ci-dessus. Pour ouvrir un fichier en lecture et en écriture, utilisezopen('file_path', 'r+')
DevShark

66

Données dans la liste

Supposons que nous ayons un fichier texte avec nos données comme dans les lignes suivantes,

Contenu du fichier texte:

line 1
line 2
line 3
  • Ouvrez la cmd dans le même répertoire (cliquez avec le bouton droit de la souris et choisissez cmd ou PowerShell)
  • Exécutez pythonet dans l'interpréteur écrivez:

Le script Python:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.rstrip("\n") for l in file]
>>> x
['line 1','line 2','line 3']

En utilisant append:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

Ou:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

Ou:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

Ou:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.rstrip("\n") for x in file]
    print_output(file)

production:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']

1
read().splitlines()est fourni par Python: c'est tout simplement readlines()(ce qui est probablement plus rapide, car c'est moins de gaspillage).
Eric O Lebigot

1
@EricOLebigot des exemples montrés, il ressemble read().splitlines()et readlines()ne produit pas la même sortie. Êtes-vous sûr qu'ils sont équivalents?
craq

1
Si vous utilisez uniquement des lignes de lecture, vous devez utiliser la méthode strip pour vous débarrasser du \ n dans le texte, j'ai donc changé les derniers exemples en utilisant une compréhension de liste pour avoir la même sortie dans les deux cas. Donc, si vous utilisez read (). Readlines () vous aurez un élément "propre" avec la ligne et sans le caractère newline, sinon, vous devez faire ce que vous voyez dans le code ci-dessus.
Giovanni G. PY

1
En effet. Notez que dans le code ci-dessus, tout strip()doit être rstrip("\n")ou les espaces autour d'une ligne sont supprimés. De plus, cela ne sert à rien de readlines()comprendre une liste: il est préférable d'itérer simplement sur le fichier, car cela ne perd pas de temps et de mémoire en créant une liste intermédiaire des lignes.
Eric O Lebigot il y a

1
@EricOLebigot Terminé, merci.
Giovanni G. PY Il y a

43

Pour lire un fichier dans une liste, vous devez faire trois choses:

  • Ouvrez le dossier
  • Lire le dossier
  • Stockez le contenu sous forme de liste

Heureusement, Python permet de faire ces choses très facilement, donc le moyen le plus court de lire un fichier dans une liste est:

lst = list(open(filename))

Cependant, je vais ajouter quelques explications supplémentaires.

Ouverture du dossier

Je suppose que vous voulez ouvrir un fichier spécifique et que vous ne traitez pas directement avec un descripteur de fichier (ou un descripteur de type fichier). La fonction la plus utilisée pour ouvrir un fichier en Python est open, elle prend un argument obligatoire et deux optionnels en Python 2.7:

  • Nom de fichier
  • Mode
  • Mise en mémoire tampon (je vais ignorer cet argument dans cette réponse)

Le nom de fichier doit être une chaîne qui représente le chemin d'accès au fichier . Par exemple:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

Notez que l'extension de fichier doit être spécifiée. Ceci est particulièrement important pour les utilisateurs de Windows car les extensions de fichiers comme .txtou .doc, etc. sont masquées par défaut lorsqu'elles sont affichées dans l'explorateur.

Le deuxième argument est le mode, c'est rpar défaut ce qui signifie "lecture seule". C'est exactement ce dont vous avez besoin dans votre cas.

Mais si vous voulez réellement créer un fichier et / ou écrire dans un fichier, vous aurez besoin d'un argument différent ici. Il y a une excellente réponse si vous voulez un aperçu .

Pour lire un fichier, vous pouvez omettre le modeou le transmettre explicitement:

open(filename)
open(filename, 'r')

Les deux ouvriront le fichier en mode lecture seule. Si vous souhaitez lire un fichier binaire sous Windows, vous devez utiliser le mode rb:

open(filename, 'rb')

Sur d'autres plateformes, le 'b'(mode binaire) est simplement ignoré.


Maintenant que j'ai montré comment archiver openle fichier, parlons du fait que vous en aurez toujours besoin close. Sinon, il conservera un descripteur de fichier ouvert jusqu'à ce que le processus se termine (ou que Python récupère le descripteur de fichier).

Bien que vous puissiez utiliser:

f = open(filename)
# ... do stuff with f
f.close()

Cela ne fermera pas le fichier lorsque quelque chose entre openet closelève une exception. Vous pouvez éviter cela en utilisant un tryet finally:

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

Cependant, Python fournit des gestionnaires de contexte qui ont une syntaxe plus jolie (mais pour openelle, elle est presque identique à celle ci try- finallydessus):

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

La dernière approche est l' approche recommandée pour ouvrir un fichier en Python!

Lecture du fichier

D'accord, vous avez ouvert le fichier, maintenant comment le lire?

La openfonction renvoie un fileobjet et prend en charge le protocole d'itération Pythons. Chaque itération vous donnera une ligne:

with open(filename) as f:
    for line in f:
        print(line)

Cela imprimera chaque ligne du fichier. Notez cependant que chaque ligne contiendra un caractère de nouvelle ligne \nà la fin (vous voudrez peut-être vérifier si votre Python est construit avec la prise en charge universelle des nouvelles lignes - sinon vous pourriez également avoir \r\nsur Windows ou \rMac en tant que nouvelles lignes). Si vous ne le souhaitez pas, vous pouvez simplement supprimer le dernier caractère (ou les deux derniers caractères sous Windows):

with open(filename) as f:
    for line in f:
        print(line[:-1])

Mais la dernière ligne n'a pas nécessairement de retour à la ligne, donc il ne faut pas l'utiliser. On pourrait vérifier s'il se termine par un retour à la ligne de fin et si oui, supprimez-le:

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

Mais vous pouvez simplement supprimer tous les espaces blancs (y compris le \ncaractère) de la fin de la chaîne , cela supprimera également tous les autres espaces blancs de fin , vous devez donc faire attention si ceux-ci sont importants:

with open(filename) as f:
    for line in f:
        print(f.rstrip())

Cependant si les lignes se terminent par \r\n("newlines" Windows) cela .rstrip()prendra également soin de \r!

Stockez le contenu sous forme de liste

Maintenant que vous savez comment ouvrir le fichier et le lire, il est temps de stocker le contenu dans une liste. L'option la plus simple serait d'utiliser la listfonction:

with open(filename) as f:
    lst = list(f)

Si vous souhaitez supprimer les sauts de ligne de fin, vous pouvez utiliser une compréhension de liste à la place:

with open(filename) as f:
    lst = [line.rstrip() for line in f]

Ou encore plus simple: la .readlines()méthode de l' fileobjet renvoie par défaut une listdes lignes:

with open(filename) as f:
    lst = f.readlines()

Cela inclura également les caractères de fin de ligne, si vous ne les voulez pas, je recommanderais l' [line.rstrip() for line in f]approche car cela évite de garder deux listes contenant toutes les lignes en mémoire.

Il existe une option supplémentaire pour obtenir la sortie souhaitée, mais elle est plutôt "sous-optimale": readle fichier complet dans une chaîne, puis divisé sur les retours à la ligne:

with open(filename) as f:
    lst = f.read().split('\n')

ou:

with open(filename) as f:
    lst = f.read().splitlines()

Ceux-ci prennent automatiquement en charge les sauts de ligne de fin car le splitpersonnage n'est pas inclus. Cependant, elles ne sont pas idéales car vous conservez le fichier sous forme de chaîne et de liste de lignes en mémoire!

Sommaire

  • À utiliser with open(...) as flors de l'ouverture de fichiers car vous n'avez pas besoin de vous occuper de la fermeture du fichier vous-même et il ferme le fichier même si une exception se produit.
  • fileles objets prennent en charge le protocole d'itération, la lecture d'un fichier ligne par ligne est donc aussi simple que for line in the_file_object:.
  • Parcourez toujours la documentation pour les fonctions / classes disponibles. La plupart du temps, il y a un match parfait pour la tâche ou au moins un ou deux bons. Le choix évident dans ce cas serait readlines()mais si vous voulez traiter les lignes avant de les stocker dans la liste, je recommanderais une simple compréhension de la liste.

La dernière approche est l'approche recommandée pour ouvrir un fichier en Python! Pourquoi est-ce que c'est le dernier, alors? La grande majorité des gens ne regardera-t-elle pas simplement les premières lignes d'une réponse avant de poursuivre?
AMC

@AMC Je n'y ai pas beaucoup réfléchi lorsque j'ai écrit la réponse. Pensez-vous que je devrais le mettre en haut de la réponse?
MSeifert

C'est peut-être mieux, oui. Je viens également de remarquer que vous mentionnez Python 2, ce qui pourrait également être mis à jour.
AMC

Ah, la question était à l'origine étiquetée python-2.x. Il peut être judicieux de le mettre à jour plus généralement. Je vais voir si j'y reviendrai la prochaine fois. Merci pour vos suggestions. Très appréciée!
MSeifert

42

Manière claire et pythonique de lire les lignes d'un fichier dans une liste


Avant tout, vous devez vous concentrer sur l'ouverture de votre fichier et la lecture de son contenu de manière efficace et pythonique. Voici un exemple de la façon dont je ne préfère pas personnellement:

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

Au lieu de cela, je préfère la méthode ci-dessous pour ouvrir des fichiers à la fois en lecture et en écriture car elle est très propre et ne nécessite pas d'étape supplémentaire de fermeture du fichier une fois que vous avez fini de l'utiliser. Dans l'instruction ci-dessous, nous ouvrons le fichier en lecture et l'assignons à la variable «infile». Une fois le code de cette instruction terminé, le fichier sera automatiquement fermé.

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

Nous devons maintenant nous concentrer sur l'intégration de ces données dans une liste Python car elles sont itérables, efficaces et flexibles. Dans votre cas, l'objectif souhaité est de placer chaque ligne du fichier texte dans un élément distinct. Pour ce faire, nous utiliserons la méthode splitlines () comme suit:

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Le produit final:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Test de notre code:

  • Contenu du fichier texte:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • Imprimer des déclarations à des fins de test:
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • Sortie (d'aspect différent en raison des caractères Unicode):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.

30

Introduit dans Python 3.4, pathliba une méthode très pratique pour lire du texte à partir de fichiers, comme suit:

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

(L' splitlinesappel est ce qui le transforme d'une chaîne contenant tout le contenu du fichier en une liste de lignes dans le fichier).

pathliba beaucoup de commodités pratiques en elle. read_textest agréable et concis, et vous n'avez pas à vous soucier de l'ouverture et de la fermeture du fichier. Si tout ce que vous avez à faire avec le fichier est de le lire en une seule fois, c'est un bon choix.


29

Voici une autre option en utilisant des compréhensions de liste sur les fichiers;

lines = [line.rstrip() for line in open('file.txt')]

Cela devrait être plus efficace car la plupart du travail se fait à l'intérieur de l'interpréteur Python.


10
rstrip()supprime potentiellement tous les espaces de fin, pas seulement le \n; utiliser .rstrip('\n').
mklement0

Cela ne garantit pas non plus que le fichier sera fermé après la lecture dans toutes les implémentations Python (bien que dans CPython, l'implémentation principale de Python, ce sera le cas).
Mark Amery

1
Cela devrait être plus efficace car la plupart du travail se fait à l'intérieur de l'interpréteur Python. Qu'est-ce que ça veut dire?
AMC

28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

Maintenant, la variable out est une liste (tableau) de ce que vous voulez. Vous pouvez soit faire:

for line in out:
    print (line)

Ou:

for line in f:
    print (line)

Vous obtiendrez les mêmes résultats.


27

Lire et écrire des fichiers texte avec Python 2 et Python 3; cela fonctionne avec Unicode

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

A noter:

  • withest un soi-disant gestionnaire de contexte . Il s'assure que le fichier ouvert est refermé.
  • Toutes les solutions ici qui font simplement .strip()ou .rstrip()ne reproduiront pas le linescar elles dépouillent également l'espace blanc.

Terminaisons de fichiers communes

.txt

Écriture / lecture de fichiers plus avancées

Pour votre application, les éléments suivants peuvent être importants:

  • Prise en charge par d'autres langages de programmation
  • Lecture / écriture
  • Compacité (taille du fichier)

Voir aussi: Comparaison des formats de sérialisation des données

Dans le cas où vous cherchez plutôt un moyen de créer des fichiers de configuration, vous voudrez peut-être lire mon court article Fichiers de configuration en Python .


26

Une autre option est numpy.genfromtxt, par exemple:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

Cela fera dataun tableau NumPy avec autant de lignes qu'il y a dans votre fichier.


25

Si vous souhaitez lire un fichier depuis la ligne de commande ou depuis stdin, vous pouvez également utiliser le fileinputmodule:

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

Passez-y des fichiers comme ceci:

$ python reader.py textfile.txt 

En savoir plus ici: http://docs.python.org/2/library/fileinput.html


20

La façon la plus simple de le faire

Un moyen simple consiste à:

  1. Lire le fichier entier sous forme de chaîne
  2. Fractionner la chaîne ligne par ligne

En une ligne, cela donnerait:

lines = open('C:/path/file.txt').read().splitlines()

Cependant, c'est assez inefficace car cela stockera 2 versions du contenu en mémoire (probablement pas un gros problème pour les petits fichiers, mais quand même). [Merci Mark Amery].

Il existe 2 façons plus simples:

  1. Utilisation du fichier comme itérateur
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Si vous utilisez Python 3.4 ou supérieur, mieux vaut pathlibcréer un chemin d'accès à votre fichier que vous pourriez utiliser pour d'autres opérations dans votre programme:
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

C'est une mauvaise approche. D'une part, appeler .read().splitlines()n'est en aucun cas "plus simple" que d'appeler.readlines() . Pour un autre, il est inefficace en mémoire; vous stockez inutilement deux versions du contenu du fichier (la chaîne unique renvoyée par .read()et la liste des chaînes renvoyées par splitlines()) en mémoire à la fois.
Mark Amery

@MarkAmery True. Merci d'avoir souligné cela. J'ai mis à jour ma réponse.
Jean-Francois T.

14

Utilisez simplement les fonctions splitlines (). Voici un exemple.

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

Dans la sortie, vous aurez la liste des lignes.


Mémoire inefficace par rapport à l'utilisation .readlines(). Cela met deux copies du contenu du fichier en mémoire à la fois (une sous forme de chaîne énorme unique, une sous forme de liste de lignes).
Mark Amery

11

Si vous voulez être confronté à un fichier très volumineux / volumineux et que vous souhaitez lire plus rapidement (imaginez que vous êtes dans un concours de codage Topcoder / Hackerrank), vous pouvez lire un bloc de lignes considérablement plus grand dans un tampon mémoire à la fois, plutôt que il suffit d'itérer ligne par ligne au niveau du fichier.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

que fait le processus (ligne)? J'obtiens une erreur indiquant qu'une telle variable n'est pas définie. Je suppose que quelque chose doit être importé et j'ai essayé d'importer le multiprocessing.Process, mais ce n'est pas ça, je suppose. Pourriez-vous s'il vous plaît développer? Merci
Newskooler

1
process(line)est une fonction que vous devez implémenter pour traiter les données. par exemple, au lieu de cette ligne, si vous utilisez print(line), il imprimera chaque ligne à partir du lines_buffer.
Khanal

f.readlines (buffersize) renvoie un tampon immuable. si vous voulez lire directement dans votre tampon, vous devez utiliser la fonction readinto (). Je serai beaucoup plus rapide.
David Dehghan

7

Les moyens les plus simples de le faire avec certains avantages supplémentaires sont les suivants:

lines = list(open('filename'))

ou

lines = tuple(open('filename'))

ou

lines = set(open('filename'))

Dans le cas de set, nous devons nous rappeler que nous n'avons pas l'ordre des lignes préservé et nous débarrasser des lignes dupliquées.

Ci-dessous, j'ai ajouté un supplément important de @MarkAmery :

Étant donné que vous n'appelez pas .closel'objet fichier ni n'utilisez une withinstruction, dans certaines implémentations Python, le fichier peut ne pas être fermé après la lecture et votre processus perdra un descripteur de fichier ouvert .

En CPython (l' implémentation Python normale que la plupart des gens utilisent), ce n'est pas un problème car l'objet fichier sera immédiatement récupéré et cela fermera le fichier, mais il est néanmoins généralement considéré comme la meilleure pratique de faire quelque chose comme :

with open('filename') as f: lines = list(f) 

pour vous assurer que le fichier est fermé quelle que soit l' implémentation Python que vous utilisez.


1
Étant donné que vous n'appelez pas .closel'objet fichier ni n'utilisez une withinstruction, dans certaines implémentations Python, le fichier peut ne pas être fermé après la lecture et votre processus perdra un descripteur de fichier ouvert. En CPython (l'implémentation Python normale que la plupart des gens utilisent), ce n'est pas un problème car l'objet fichier sera immédiatement récupéré et cela fermera le fichier, mais il est néanmoins généralement considéré comme la meilleure pratique de faire quelque chose comme with open('filename') as f: lines = list(f)pour s'assurer que le fichier est fermé quelle que soit l'implémentation Python que vous utilisez.
Mark Amery

Merci pour votre excellent commentaire @MarkAmery! J'apprécie vraiment cela.
simhumileco

1
@simhumileco Pourquoi avoir la meilleure (bonne) solution en dernier?
AMC

@AMC parce que d'abord, je voulais montrer les moyens les plus simples et pour la cohérence du raisonnement.
simhumileco

D'ailleurs, j'espère que ma réponse est faite pour qu'elle soit courte et facile à lire.
simhumileco

4

Utilisez ceci:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

dataest un type de trame de données et utilise des valeurs pour obtenir ndarray. Vous pouvez également obtenir une liste en utilisant array.tolist().


pandas.read_csv()est pour la lecture des données CSV , comment est-il approprié ici?
AMC

4

Aperçu et résumé

Avec un filename, en manipulant le fichier à partir d'un Path(filename)objet, ou directement avec open(filename) as f, effectuez l'une des opérations suivantes:

  • list(fileinput.input(filename))
  • utiliser with path.open() as f, appelerf.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • itérer sur fileinput.inputou fetlist.append chaque ligne une à la fois
  • passer fà une limitelist.extend méthode
  • utiliser fdans une liste de compréhension

J'explique le cas d'utilisation pour chacun ci-dessous.

En Python, comment lire un fichier ligne par ligne?

Ceci est une excellente question. Commençons par créer des exemples de données:

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

Les objets fichier sont des itérateurs paresseux, il suffit donc d'itérer dessus.

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

Alternativement, si vous avez plusieurs fichiers, utilisez fileinput.inputun autre itérateur paresseux. Avec un seul fichier:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

ou pour plusieurs fichiers, passez-lui une liste de noms de fichiers:

for line in fileinput.input([filename]*2): 
    line # process the line

Encore fet fileinput.inputsurtout, les deux sont / retournent des itérateurs paresseux. Vous ne pouvez utiliser un itérateur qu'une seule fois, donc pour fournir du code fonctionnel tout en évitant la verbosité, j'utiliserai le légèrement plus concis fileinput.input(filename)où il est proposé d'ici.

En Python, comment lire un fichier ligne par ligne dans une liste?

Ah mais vous le voulez dans une liste pour une raison quelconque? J'éviterais cela si possible. Mais si vous insistez ... passez simplement le résultat de fileinput.input(filename)à list:

list(fileinput.input(filename))

Une autre réponse directe consiste à appeler f.readlines, qui renvoie le contenu du fichier (jusqu'à un hintnombre facultatif de caractères, vous pouvez donc décomposer en plusieurs listes de cette façon).

Vous pouvez accéder à cet objet fichier de deux manières. Une façon consiste à passer le nom de fichier au openmodule intégré:

filename = 'filename'

with open(filename) as f:
    f.readlines()

ou en utilisant le nouvel objet Path du pathlibmodule (que j'aime beaucoup et que j'utiliserai à partir de maintenant):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list consommera également l'itérateur de fichier et renverra une liste - une méthode assez directe également:

with path.open() as f:
    list(f)

Si cela ne vous dérange pas de lire le texte entier en mémoire comme une seule chaîne avant de le fractionner, vous pouvez le faire en une ligne avec l' Pathobjet et la splitlines()méthode de chaîne. Par défaut, splitlinessupprime les sauts de ligne:

path.read_text().splitlines()

Si vous souhaitez conserver les nouvelles lignes, passez keepends=True:

path.read_text().splitlines(keepends=True)

Je veux lire le fichier ligne par ligne et ajouter chaque ligne à la fin de la liste.

Maintenant, c'est un peu idiot de demander, étant donné que nous avons facilement démontré le résultat final avec plusieurs méthodes. Mais vous devrez peut-être filtrer ou opérer sur les lignes lors de la création de votre liste, alors humorisons cette demande.

L'utilisation list.appendvous permettrait de filtrer ou d'opérer sur chaque ligne avant de l'ajouter:

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

L'utilisation list.extendserait un peu plus directe, et peut-être utile si vous avez une liste préexistante:

line_list = []
line_list.extend(fileinput.input(filename))
line_list

Ou plus idiomatiquement, nous pourrions plutôt utiliser une liste de compréhension, et mapper et filtrer à l'intérieur si cela est souhaitable:

[line for line in fileinput.input(filename)]

Ou encore plus directement, pour fermer le cercle, il suffit de le passer à list pour créer directement une nouvelle liste sans opérer sur les lignes:

list(fileinput.input(filename))

Conclusion

Vous avez vu de nombreuses façons d'obtenir des lignes d'un fichier dans une liste, mais je vous recommande d'éviter de matérialiser de grandes quantités de données dans une liste et d'utiliser à la place l'itération paresseuse de Python pour traiter les données si possible.

Autrement dit, préférez fileinput.inputou with path.open() as f.


4

Dans le cas où il y a aussi des lignes vides dans le document, j'aime lire le contenu et le passer filterpour éviter les éléments de chaîne vides

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))

1
C'est impythonique, soyez prudent.
AMC

3

Vous pouvez également utiliser la commande loadtxt dans NumPy. Cela vérifie moins de conditions que genfromtxt, il peut donc être plus rapide.

import numpy
data = numpy.loadtxt(filename, delimiter="\n")

2

J'aime utiliser ce qui suit. Lecture immédiate des lignes.

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

Ou en utilisant la compréhension de liste:

contents = [line.strip() for line in open(filepath, 'r').readlines()]

2
Il n'y en a pas besoin readlines(), ce qui entraîne même une pénalité de mémoire. Vous pouvez simplement le supprimer, car l'itération sur un fichier (texte) donne chaque ligne tour à tour.
Eric O Lebigot

2
Vous devez utiliser une withinstruction pour ouvrir (et fermer implicitement) le fichier.
Aran-Fey

2

J'essaierais l'une des méthodes mentionnées ci-dessous. Le fichier d'exemple que j'utilise porte le nom dummy.txt. Vous pouvez trouver le fichier ici . Je suppose que le fichier se trouve dans le même répertoire que le code (vous pouvez modifier fpathpour inclure le nom de fichier et le chemin de dossier appropriés.)

Dans les deux exemples mentionnés ci-dessous, la liste que vous souhaitez est donnée par lst.

1.> Première méthode :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.> Dans la deuxième méthode , on peut utiliser le module csv.reader de la bibliothèque standard Python :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

Vous pouvez utiliser l'une des deux méthodes. Le temps nécessaire à la création de lstest presque égal dans les deux méthodes.


1
Quel est l'avantage de la deuxième approche? Pourquoi invoquer une bibliothèque supplémentaire, qui ajoute des cas marginaux (le délimiteur et les guillemets)?
Charlie Harding

À quoi sert l' delimiter=' 'argument?
AMC

2

Voici une classe de bibliothèque d' assistance Python (3) que j'utilise pour simplifier les E / S de fichiers:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

Vous utiliseriez alors la FileIO.linesfonction, comme ceci:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

N'oubliez pas que mode( "r"par défaut) etfilter_fn paramètres (vérifie les lignes vides par défaut) sont facultatifs.

Vous pouvez même retirer les read, writeet les deleteméthodes et juste laisser le FileIO.lines, ou même en faire une méthode distincte appelée read_lines.


Est-ce lines = FileIO.lines(path)vraiment assez simple with open(path) as f: lines = f.readlines()pour justifier l'existence de cet assistant? Vous économisez, par exemple, 17 caractères par appel. (Et la plupart du temps, pour des raisons de performances et de mémoire, vous voudrez boucler directement sur un objet fichier au lieu de lire ses lignes dans une liste de toute façon, donc vous ne voudrez même pas l'utiliser souvent!) souvent fan de créer de petites fonctions utilitaires, mais celui-ci me semble comme créer simplement inutilement une nouvelle façon d'écrire quelque chose qui est déjà court et facile avec la bibliothèque standard.
Mark Amery

En plus de ce que @MarkAmery a dit, pourquoi utiliser une classe pour cela?
AMC

1

Version en ligne de commande

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

Courir avec:

python3 somefile.py input_file_name.txt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.