Odpowiedzi:
Jeśli plik do odczytu jest duży i nie chcesz jednocześnie czytać całego pliku w pamięci:
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()
Zauważ, że i == n-1dla nlinii th.
W Pythonie 2.6 lub nowszym:
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)używa x.next, więc nie potrzebuje całego pliku w pamięci.
big file. Pętla zajmie lata, aby dotrzeć do indeksu
Szybka odpowiedź:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
lub:
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
Istnieje bardziej eleganckie rozwiązanie do wyodrębniania wielu wierszy: linecache (dzięki uprzejmości „python: jak przejść do konkretnej linii w ogromnym pliku tekstowym?” , Poprzednie pytanie stackoverflow.com).
Cytując powyższą dokumentację w języku Python:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
Zmień 4żądany numer linii i gotowe. Zauważ, że 4 przyniosłoby piątą linię, ponieważ liczba jest liczona od zera.
Jeśli plik może być bardzo duży i powodować problemy podczas wczytywania do pamięci, dobrym pomysłem może być skorzystanie z porady @ Alok i użycie funkcji enumerate () .
Podsumowując:
fileobject.readlines()lub for line in fileobjectjako szybkiego rozwiązania dla małych plików.linecachedo bardziej eleganckiego rozwiązania, które będzie dość szybkie do odczytu wielu plików, możliwe wielokrotnie.enumerate() plików, które mogą być bardzo duże i nie zmieściłyby się w pamięci. Pamiętaj, że użycie tej metody może spowolnić, ponieważ plik jest odczytywany sekwencyjnie.linecachemodułu i wygląda na to, że czyta cały plik z pamięci. Tak więc, jeśli losowy dostęp jest ważniejszy niż optymalizacja rozmiaru, linecachejest najlepszą metodą.
linecacheteraz wydaje się działać tylko dla plików źródłowych Pythona
linecache.getlines('/etc/passwd')[0:4]do czytania pierwszego, drugiego, trzeciego i czwartego wiersza.
Szybkie i kompaktowe podejście mogłoby być:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
akceptuje to dowolny otwarty obiekt podobny do pliku thefile(pozostawiając programowi wywołującemu, czy należy go otworzyć z pliku dyskowego, czy np. przez gniazdo lub inny strumień podobny do pliku) i zestaw wskaźników wiersza od zera whatlines, i zwraca lista, z małą powierzchnią pamięci i rozsądną prędkością. Jeśli liczba zwracanych wierszy jest ogromna, możesz preferować generator:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
co w zasadzie jest dobre tylko do zapętlania - zwróć uwagę, że jedyna różnica wynika z użycia w returninstrukcji zaokrąglonych, a nie kwadratowych nawiasów , dzięki czemu możliwe jest zrozumienie listy i wyrażenie generatora.
Zwróć też uwagę, że pomimo wzmianki o „wierszach” i „pliku” funkcje te są znacznie, znacznie bardziej ogólne - będą działać na każdym iterowalnym, czy to otwartym pliku, czy innym, zwracając listę (lub generator) elementów na podstawie ich progresywnych numerów przedmiotów. Sugeruję więc stosowanie bardziej odpowiednio ogólnych nazw ;-).
whatlinespowinno być set, ponieważ if i in whatlinesbędzie działać szybciej z zestawem niż (posortowaną) listą. Nie zauważyłem tego po raz pierwszy i zamiast tego opracowałem własne brzydkie rozwiązanie z posortowaną listą (gdzie nie musiałem skanować listy za każdym razem, podczas gdyif i in whatlines tylko to robi), ale różnica w wydajności była znikoma (z moimi danymi) i to rozwiązanie jest znacznie bardziej eleganckie.
Aby zaoferować inne rozwiązanie:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
Mam nadzieję, że to szybkie i łatwe :)
jeśli chcesz wiersz 7
line = open („file.txt”, „r”). readlines () [7]
close()plik, otwierając go w ten sposób?
Dla kompletności, oto jeszcze jedna opcja.
Zacznijmy od definicji z dokumentacji Pythona :
plasterek Obiekt zwykle zawierający część sekwencji. Wycinek jest tworzony za pomocą notacji indeksu dolnego [] z dwukropkami między liczbami, gdy podano kilka, na przykład w zmiennej_nazwa [1: 3: 5]. Notacja w nawiasach (indeks dolny) wykorzystuje obiekty wycinków wewnętrznie (lub w starszych wersjach __getslice __ () i __setslice __ ()).
Chociaż notacja wycinka nie ma bezpośredniego zastosowania do iteratorów, itertoolspakiet zawiera funkcję zastępowania:
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
Dodatkową zaletą tej funkcji jest to, że nie czyta iteratora do końca. Możesz więc robić bardziej złożone rzeczy:
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
Aby odpowiedzieć na pierwotne pytanie:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
Odczytywanie plików jest niesamowicie szybkie. Odczyt pliku 100 MB zajmuje mniej niż 0,1 sekundy (zobacz mój artykuł Odczytywanie i zapisywanie plików w Pythonie ). Dlatego powinieneś przeczytać go całkowicie, a następnie pracować z pojedynczymi wierszami.
Większość odpowiedzi tutaj nie jest zła, ale zły styl. Zawsze należy otwierać plikiwith ponieważ zapewnia to, że plik zostanie ponownie zamknięty.
Więc powinieneś to zrobić w ten sposób:
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
Jeśli zdarzy ci się mieć ogromny plik i zużycie pamięci stanowi problem, możesz go przetworzyć wiersz po wierszu:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
Niektóre z nich są piękne, ale można to zrobić o wiele prościej:
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)
Wykorzysta to proste wycinanie list, ładuje cały plik, ale większość systemów odpowiednio zminimalizuje zużycie pamięci, jest szybsza niż większość metod podanych powyżej i działa na moich plikach danych 10G +. Powodzenia!
Możesz wykonać wywołanie seek (), które pozycjonuje twoją głowicę odczytu do określonego bajtu w pliku. To ci nie pomoże, chyba że dokładnie wiesz, ile bajtów (znaków) zapisano w pliku przed wierszem, który chcesz przeczytać. Być może twój plik jest ściśle sformatowany (każda linia ma liczbę X bajtów?) Lub możesz sam policzyć liczbę znaków (pamiętaj o dołączaniu niewidocznych znaków, takich jak podział linii), jeśli naprawdę chcesz przyspieszenia.
W przeciwnym razie musisz przeczytać każdą linię przed linią, której chcesz, zgodnie z jednym z wielu rozwiązań już tutaj zaproponowanych.
Jeśli twój duży plik tekstowy filema ściśle dobrą strukturę (co oznacza, że każda linia ma tę samą długość l), możesz użyć dla n-tego wiersza
with open(file) as f:
f.seek(n*l)
line = f.readline()
last_pos = f.tell()
Oświadczenie Działa to tylko w przypadku plików o tej samej długości!
Co powiesz na to:
>>> 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()
Jeśli nie przeszkadza Ci importowanie, fileinput wykonuje dokładnie to, czego potrzebujesz (możesz odczytać numer bieżącej linii)
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
Wolę to podejście, ponieważ jest bardziej ogólne, tzn. Możesz użyć go w pliku, w wyniku f.readlines(), na StringIOobiekcie, cokolwiek:
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']
Oto moje małe 2 centy, za ile są warte;)
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])
Lepsza i drobna zmiana w odpowiedzi Aloka Singhala
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()
Obiekty plików mają metodę .readlines (), która daje listę zawartości pliku, po jednej linii na element listy. Następnie możesz po prostu użyć normalnych technik dzielenia listy.
@OP, możesz użyć wyliczenia
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]
Za pomocą instrukcji with otwiera to plik, drukuje linie 26 i 30, a następnie zamyka plik. Prosty!
readlines()iteratora wyczerpie się, a drugie wywołanie zwróci pustą listę lub wyrzuci błąd (nie pamiętam, które)
Możesz to zrobić bardzo prosto, korzystając ze składni, o której ktoś już wspomniał, ale jest to zdecydowanie najłatwiejszy sposób:
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
Aby wydrukować linię nr 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
Oryginalny autor: Frank Hofmann
Aby wydrukować określone wiersze w pliku tekstowym. Utwórz listę „lines2print”, a następnie po prostu wydrukuj, gdy wyliczenie jest „na” liście lines2print. Aby pozbyć się dodatkowych „\ n”, użyj line.strip () lub line.strip ('\ n'). Po prostu lubię „rozumienie listy” i staram się używać, kiedy mogę. Lubię metodę „with” do czytania plików tekstowych, aby zapobiec pozostawieniu pliku otwartego z jakiegokolwiek powodu.
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]
lub jeśli lista jest mała, po prostu wpisz listę jako listę do zrozumienia.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]
Aby wydrukować żądaną linię. Aby wydrukować linię powyżej / poniżej wymaganej linii.
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()
wykonaj ----> dline („D: \ dummy.txt”, 6) tj. dline („ścieżka pliku”, numer_wiersza, jeśli chcesz, aby górna linia szukanej linii dawała 1 dla dolnej -1, jest to opcjonalna wartość domyślna będzie być zajęty 0)
Jeśli chcesz odczytać określone linie, takie jak linia rozpoczynająca się po pewnej linii progowej, możesz użyć następujących kodów,
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()
Myślę, że to zadziała
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]