J'utilise une boucle for pour lire un fichier, mais je veux seulement lire des lignes spécifiques, par exemple les lignes 26 et 30. Existe-t-il une fonctionnalité intégrée pour y parvenir?
Merci
Si le fichier à lire est volumineux et que vous ne voulez pas lire tout le fichier en mémoire à la fois:
fp = open("file")
for i, line in enumerate(fp):
if i == 25:
# 26th line
Elif i == 29:
# 30th line
Elif i > 29:
break
fp.close()
Notez que i == n-1
pour la n
th ligne.
En Python 2.6 ou version ultérieure:
with open("file") as fp:
for i, line in enumerate(fp):
if i == 25:
# 26th line
Elif i == 29:
# 30th line
Elif i > 29:
break
La réponse rapide:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
ou:
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
Il existe une solution plus élégante pour extraire de nombreuses lignes: linecache (avec la permission de "python: comment passer à une ligne particulière dans un fichier texte énorme?" , une question précédente de stackoverflow.com).
Citant la documentation python liée ci-dessus:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
Remplacez le 4
par le numéro de ligne souhaité et le tour est joué. Notez que 4 amènerait la cinquième ligne car le compte est basé sur zéro.
Si le fichier est volumineux et pose des problèmes de lecture, il peut être judicieux de suivre les conseils de @ Alok et d'utiliser enumerate () .
De conclure:
fileobject.readlines()
ou for line in fileobject
comme solution rapide pour les petits fichiers. linecache
pour une solution plus élégante, qui sera assez rapide pour lire de nombreux fichiers, possible plusieurs fois.enumerate()
pour les fichiers pouvant être volumineux et ne pas tenir dans la mémoire. Notez que l'utilisation de cette méthode peut être ralentie car le fichier est lu séquentiellement.Une approche rapide et compacte pourrait être:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
cela accepte tout objet ressemblant à un fichier ouvert thefile
(laissant à l'appelant le choix d'ouvrir ou non à partir d'un fichier disque, ou via un socket, ou tout autre flux de type fichier) et un ensemble d'index de ligne de base zéro whatlines
, et renvoie une liste, avec une faible empreinte mémoire et une vitesse raisonnable. Si le nombre de lignes à renvoyer est énorme, vous pouvez préférer un générateur:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
notez que la seule différence provient de l’utilisation de parenthèses arrondies plutôt que carrées dans l’instruction return
, permettant ainsi une compréhension de la liste et une expression génératrice.
Notez en outre que, malgré la mention des "lignes" et du "fichier", ces fonctions sont très nombreuses, beaucoup plus général - elles fonctionneront sur toutes -, ce sera un fichier ouvert ou autre, retournant une liste (ou un générateur) d’articles en fonction de leur numéro d’article progressif. Donc, je suggérerais d'utiliser des noms généraux plus appropriés ;-).
Pour proposer une autre solution:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
J'espère que c'est rapide et facile :)
si vous voulez la ligne 7
line = open ("fichier.txt", "r"). readlines () [7]
Par souci d'exhaustivité, voici une autre option.
Commençons par une définition de python docs :
slice Un objet contenant généralement une partie d'une séquence. Une tranche est créée à l'aide de la notation en indice, [] avec des points entre deux chiffres lorsque plusieurs sont indiqués, comme dans nom_variable [1: 3: 5]. La notation crochet (indice) utilise les objets slice en interne (ou dans les versions antérieures, __getslice __ () et __setslice __ ()).
Bien que la notation de tranche ne soit pas directement applicable aux itérateurs, le paquetage itertools
contient une fonction de remplacement:
from itertools import islice
# print the 100th line
with open('the_file') as lines:
for line in islice(lines, 99, 100):
print line
# print each third line until 100
with open('the_file') as lines:
for line in islice(lines, 0, 100, 3):
print line
L'avantage supplémentaire de la fonction est qu'elle ne lit pas l'itérateur jusqu'à la fin. Vous pouvez donc faire des choses plus complexes:
with open('the_file') as lines:
# print the first 100 lines
for line in islice(lines, 100):
print line
# then skip the next 5
for line in islice(lines, 5):
pass
# print the rest
for line in lines:
print line
Et pour répondre à la question initiale:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
Lire des fichiers est incroyablement rapide. La lecture d’un fichier de 100 Mo prend moins de 0,1 seconde (voir mon article Lecture et écriture de fichiers avec Python ). Par conséquent, vous devriez le lire complètement et ensuite travailler avec les lignes simples.
Ce que la plupart des gens répondent ici n’est pas mauvais, mais mauvais style L’ouverture des fichiers doit toujours se faire avec with
car cela permet de s’assurer que le fichier est refermé.
Donc, vous devriez le faire comme ceci:
with open("path/to/file.txt") as f:
lines = f.readlines()
print(lines[26]) # or whatever you want to do with this line
print(lines[30]) # or whatever you want to do with this line
Si vous avez beaucoup de fichiers et que la consommation de mémoire est un problème, vous pouvez le traiter ligne par ligne:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
Certaines d'entre elles sont belles, mais cela peut être fait beaucoup plus simplement:
start = 0 # some starting index
end = 5000 # some ending index
filename = 'test.txt' # some file we want to use
with open(filename) as fh:
data = fin.readlines()[start:end]
print(data)
Cela utilisera simplement le découpage de liste, il chargera le fichier entier, mais la plupart des systèmes minimiseront l'utilisation de la mémoire de manière appropriée, il est plus rapide que la plupart des méthodes indiquées ci-dessus et fonctionne sur mes fichiers de données 10G +. Bonne chance!
Vous pouvez faire un appel seek () qui positionne votre tête de lecture sur un octet spécifié du fichier. Cela ne vous aidera pas si vous ne savez pas exactement combien d'octets (caractères) sont écrits dans le fichier avant la ligne que vous voulez lire. Peut-être que votre fichier est strictement formaté (chaque ligne correspond à un nombre X d'octets?) Ou vous pouvez compter vous-même le nombre de caractères (n'oubliez pas d'inclure des caractères invisibles comme des sauts de ligne) si vous voulez vraiment augmenter la vitesse.
Sinon, vous devez lire chaque ligne avant la ligne souhaitée, conformément à l'une des nombreuses solutions déjà proposées ici.
Que dis-tu de ça:
>>> with open('a', 'r') as fin: lines = fin.readlines()
>>> for i, line in enumerate(lines):
if i > 30: break
if i == 26: dox()
if i == 30: doy()
Un changement meilleur et mineur pour la réponse d'Alok Singhal
fp = open("file")
for i, line in enumerate(fp,1):
if i == 26:
# 26th line
Elif i == 30:
# 30th line
Elif i > 30:
break
fp.close()
Je préfère cette approche car elle est plus polyvalente, c’est-à-dire que vous pouvez l’utiliser sur un fichier, sur le résultat de f.readlines()
, sur un objet StringIO
, peu importe:
def read_specific_lines(file, lines_to_read):
"""file is any iterable; lines_to_read is an iterable containing int values"""
lines = set(lines_to_read)
last = max(lines)
for n, line in enumerate(file):
if n + 1 in lines:
yield line
if n + 1 > last:
return
>>> with open(r'c:\temp\words.txt') as f:
[s for s in read_specific_lines(f, [1, 2, 3, 1000])]
['A\n', 'a\n', 'aa\n', 'accordant\n']
Si cela ne vous dérange pas d’importer alors fileinput fait exactement ce dont vous avez besoin (c’est vous pouvez lire le numéro de la ligne courante)
def getitems(iterable, items):
items = list(items) # get a list from any iterable and make our own copy
# since we modify it
if items:
items.sort()
for n, v in enumerate(iterable):
if n == items[0]:
yield v
items.pop(0)
if not items:
break
print list(getitems(open("/usr/share/dict/words"), [25, 29]))
# ['Abelson\n', 'Abernathy\n']
# note that index 25 is the 26th item
Voici mes 2 centimes, pour ce que ça vaut;)
def indexLines(filename, lines=[2,4,6,8,10,12,3,5,7,1]):
fp = open(filename, "r")
src = fp.readlines()
data = [(index, line) for index, line in enumerate(src) if index in lines]
fp.close()
return data
# Usage below
filename = "C:\\Your\\Path\\And\\Filename.txt"
for line in indexLines(filename): # using default list, specify your own list of lines otherwise
print "Line: %s\nData: %s\n" % (line[0], line[1])
file = '/path/to/file_to_be_read.txt'
with open(file) as f:
print f.readlines()[26]
print f.readlines()[30]
En utilisant l'instruction with, cela ouvre le fichier, imprime les lignes 26 et 30, puis ferme le fichier. Simple!
Les objets de fichier ont une méthode .readlines () qui vous donnera une liste du contenu du fichier, une ligne par élément de la liste. Après cela, vous pouvez simplement utiliser les techniques de découpage de liste normales.
Vous pouvez le faire très simplement avec cette syntaxe déjà mentionnée par quelqu'un, mais c'est de loin le moyen le plus simple de le faire:
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
Pour imprimer la ligne n ° 3,
line_number = 3
with open(filename,"r") as file:
current_line = 1
for line in file:
if current_line == line_number:
print(file.readline())
break
current_line += 1
Auteur original: Frank Hofmann
@OP, vous pouvez utiliser énumérer
for n,line in enumerate(open("file")):
if n+1 in [26,30]: # or n in [25,29]
print line.rstrip()
Si votre fichier texte volumineux file
est strictement bien structuré (chaque ligne a la même longueur l
), vous pouvez utiliser pour n
- ème ligne
with open(file) as f:
f.seek(n*l)
line = f.readline() # please notice the s at the end!
last_pos = f.tell()
Avertissement Ceci ne fonctionne que pour les fichiers de la même longueur!
Pour imprimer la ligne désirée .. Pour imprimer la ligne située au-dessus/au-dessous de la ligne requise.
def dline(file,no,add_sub=0):
tf=open(file)
for sno,line in enumerate(tf):
if sno==no-1+add_sub:
print(line)
tf.close()
execute ----> dline ("D:\dummy.txt", 6) c'est-à-dire dline ("chemin du fichier", numéro_ligne, si vous voulez que la ligne supérieure de la ligne recherchée donne 1 pour inférieur -1, il s'agit d'une valeur par défaut facultative être pris 0)
Pour imprimer certaines lignes dans un fichier texte. Créez une liste "lines2print" puis Imprimez simplement lorsque l'énumération est "dans" la liste lines2print . Pour vous débarrasser des '\ n' supplémentaires, utilisez line.strip () ou line.strip ('\ n ') . J'aime juste "comprendre la liste" et essayer d'utiliser quand je peux . J'aime la méthode "avec" pour lire les fichiers texte afin d'empêcher De laisser un fichier ouvert pour une raison quelconque.
lines2print = [26,30] # can be a big list and order doesn't matter.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in lines2print]
ou si la liste est petite, il suffit de taper la liste comme liste dans la compréhension.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]