Risposte:
Se il file da leggere è grande e non si desidera leggere l'intero file in memoria contemporaneamente:
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()
Si noti che i == n-1
per la n
linea th.
In Python 2.6 o successivo:
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
enumerate(x)
utilizza x.next
, quindi non necessita dell'intero file in memoria.
big file
. Il ciclo richiederà anni per raggiungere l'indice
La risposta rapida:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
o:
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
Esiste una soluzione più elegante per l'estrazione di molte righe: linecache (per gentile concessione di "python: come passare a una riga particolare in un enorme file di testo?" , Una domanda precedente su stackoverflow.com).
Citando la documentazione di Python collegata sopra:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
Cambia il 4
numero di riga desiderato e il gioco è fatto. Si noti che 4 porterebbe la quinta riga poiché il conteggio è a base zero.
Se il file potrebbe essere molto grande e causare problemi durante la lettura in memoria, potrebbe essere una buona idea seguire i consigli di @ Alok e utilizzare enumerate () .
Concludere:
fileobject.readlines()
o for line in fileobject
come soluzione rapida per file di piccole dimensioni.linecache
per una soluzione più elegante, che sarà abbastanza veloce per la lettura di molti file, possibile più volte.enumerate()
per i file che potrebbero essere molto grande, e non si adatta in memoria. Si noti che l'utilizzo di questo metodo potrebbe rallentare perché il file viene letto in sequenza.linecache
modulo e sembra che legga l'intero file in memoria. Quindi, se l'accesso casuale è più importante dell'ottimizzazione delle dimensioni, linecache
è il metodo migliore.
linecache
ora sembra funzionare solo con i file sorgente di Python
linecache.getlines('/etc/passwd')[0:4]
per leggere la prima, la seconda, la terza e la quarta riga.
Un approccio rapido e compatto potrebbe essere:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
questo accetta qualsiasi oggetto simile a un file aperto thefile
(lasciando al chiamante se deve essere aperto da un file su disco o tramite ad esempio un socket o un altro flusso simile a un file) e un insieme di indici di linea a base zero whatlines
e restituisce un elenco, con ingombro di memoria ridotto e velocità ragionevole. Se il numero di righe da restituire è enorme, potresti preferire un generatore:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
che è sostanzialmente buono solo per fare un ciclo su - nota che l'unica differenza deriva dall'uso di parentesi arrotondate anziché quadrate nell'istruzione return
, facendo rispettivamente una comprensione della lista e un'espressione del generatore.
Inoltre, nonostante la menzione di "linee" e "file", queste funzioni sono molto, molto più generali: funzioneranno su qualsiasi iterabile, sia esso un file aperto o altro, restituendo un elenco (o generatore) di elementi in base al numero progressivo degli articoli. Quindi, suggerirei di usare nomi più appropriatamente generali ;-).
whatlines
dovrebbe essere un set
, perché if i in whatlines
verrà eseguito più velocemente con un set piuttosto che un elenco (ordinato). Non me ne sono accorto prima e invece ho ideato la mia brutta soluzione con un elenco ordinato (in cui non ho dovuto scansionare un elenco ogni volta, mentre lo if i in whatlines
fa), ma la differenza di prestazioni era trascurabile (con i miei dati) e questo la soluzione è molto più elegante.
Per offrire un'altra soluzione:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
Spero che sia facile e veloce :)
se vuoi la linea 7
line = open ("file.txt", "r"). readlines () [7]
close()
aprire il file in questo modo?
Per completezza, ecco un'altra opzione.
Cominciamo con una definizione dai documenti di Python :
slice Un oggetto che di solito contiene una porzione di una sequenza. Viene creata una sezione utilizzando la notazione del pedice, [] con due punti tra i numeri quando ne vengono indicati diversi, come in nome_varia [1: 3: 5]. La notazione parentesi (pedice) utilizza oggetti slice internamente (o nelle versioni precedenti, __getslice __ () e __setslice __ ()).
Sebbene la notazione delle sezioni non sia direttamente applicabile agli iteratori in generale, il itertools
pacchetto contiene una funzione di sostituzione:
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
Il vantaggio aggiuntivo della funzione è che non legge l'iteratore fino alla fine. Quindi puoi fare cose più complesse:
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
E per rispondere alla domanda originale:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
La lettura dei file è incredibilmente veloce. La lettura di un file da 100 MB richiede meno di 0,1 secondi (vedere il mio articolo Lettura e scrittura di file con Python ). Quindi dovresti leggerlo completamente e quindi lavorare con le singole righe.
Ciò che la maggior parte delle risposte qui non è sbagliato, ma cattivo stile. L'apertura dei file dovrebbe sempre essere eseguita conwith
poiché garantisce che il file venga nuovamente chiuso.
Quindi dovresti farlo in questo modo:
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
Se ti capita di avere un enorme file e il consumo di memoria è un problema, puoi elaborarlo riga per riga:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
Alcuni di questi sono adorabili, ma può essere fatto molto più semplicemente:
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)
Questo userà semplicemente il list slicing, caricherà l'intero file, ma la maggior parte dei sistemi minimizzerà in modo appropriato l'utilizzo della memoria, è più veloce della maggior parte dei metodi indicati sopra e funziona sui miei file di dati 10G +. In bocca al lupo!
È possibile effettuare una chiamata seek () che posiziona la testina di lettura su un byte specificato all'interno del file. Questo non ti aiuterà se non sai esattamente quanti byte (caratteri) sono scritti nel file prima della riga che vuoi leggere. Forse il tuo file è rigorosamente formattato (ogni riga è il numero X di byte?) Oppure potresti contare tu stesso il numero di caratteri (ricordati di includere caratteri invisibili come le interruzioni di riga) se vuoi davvero aumentare la velocità.
Altrimenti, devi leggere ogni riga prima della riga che desideri, secondo una delle tante soluzioni già proposte qui.
Se il tuo file di testo di grandi dimensioni file
è rigorosamente ben strutturato (il che significa che ogni riga ha la stessa lunghezza l
), puoi utilizzare per n
-th line
with open(file) as f:
f.seek(n*l)
line = f.readline()
last_pos = f.tell()
Dichiarazione di non responsabilità Funziona solo con file della stessa lunghezza!
Cosa ne pensi di questo:
>>> 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()
Se non ti dispiace importare, fileinput fa esattamente quello che ti serve (questo è possibile leggere il numero di riga della riga corrente)
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
Preferisco questo approccio perché è più generico, cioè puoi usarlo su un file, sul risultato di f.readlines()
, su un StringIO
oggetto, qualunque cosa:
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']
Ecco i miei piccoli 2 centesimi, per quello che vale;)
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])
Gli oggetti file hanno un metodo .readlines () che ti darà un elenco dei contenuti del file, una riga per ogni elemento dell'elenco. Successivamente, puoi semplicemente utilizzare le normali tecniche di suddivisione in elenchi.
@OP, puoi usare enumerate
for n,line in enumerate(open("file")):
if n+1 in [26,30]: # or n in [25,29]
print line.rstrip()
file = '/path/to/file_to_be_read.txt'
with open(file) as f:
print f.readlines()[26]
print f.readlines()[30]
Usando l'istruzione with, questo apre il file, stampa le linee 26 e 30, quindi chiude il file. Semplice!
readlines()
all'iteratore sarà esaurita e la seconda chiamata restituirà un elenco vuoto o genererà un errore (non ricordo quale)
Puoi farlo molto semplicemente con questa sintassi che qualcuno ha già menzionato, ma è di gran lunga il modo più semplice per farlo:
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
Per stampare la linea 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
Autore originale: Frank Hofmann
Per stampare determinate righe in un file di testo. Creare un elenco "lines2print" e quindi stampare quando l'enumerazione è "nell'elenco" di lines2print. Per sbarazzarti di '\ n' extra usa line.strip () o line.strip ('\ n'). Mi piace solo la "comprensione delle liste" e provo a usarla quando posso. Mi piace il metodo "with" per leggere i file di testo per evitare di lasciare un file aperto per qualsiasi motivo.
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]
o se la lista è piccola basta digitare la lista come lista nella comprensione.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]
Per stampare la linea desiderata. Per stampare la riga sopra / sotto la riga richiesta.
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()
esegui ----> dline ("D: \ dummy.txt", 6) cioè dline ("percorso file", numero_stampa, se vuoi la linea superiore della linea cercata, dai 1 per -1 inferiore, questo è il valore predefinito opzionale essere preso 0)
Se desideri leggere righe specifiche, ad esempio la riga che inizia dopo alcune righe di soglia, puoi utilizzare i seguenti codici,
file = open("files.txt","r")
lines = file.readlines() ## convert to list of lines
datas = lines[11:] ## raed the specific lines
f = open(filename, 'r')
totalLines = len(f.readlines())
f.close()
f = open(filename, 'r')
lineno = 1
while lineno < totalLines:
line = f.readline()
if lineno == 26:
doLine26Commmand(line)
elif lineno == 30:
doLine30Commmand(line)
lineno += 1
f.close()
Penso che funzionerebbe
open_file1 = open("E:\\test.txt",'r')
read_it1 = open_file1.read()
myline1 = []
for line1 in read_it1.splitlines():
myline1.append(line1)
print myline1[0]