Я использую цикл for для чтения файла, но я хочу только прочитать определенные строки, например строки # 26 и # 30. Есть ли встроенная функция для достижения этой цели?
Спасибо
Я использую цикл for для чтения файла, но я хочу только прочитать определенные строки, например строки # 26 и # 30. Есть ли встроенная функция для достижения этой цели?
Спасибо
Если файл для чтения большой, и вы не хотите сразу читать весь файл в памяти:
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()
Обратите внимание, что i == n-1
для n
-й строки.
В Python 2.6 или новее:
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
Быстрый ответ:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
или
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
Существует более элегантное решение для извлечения многих строк: linecache (любезно предоставлено python: как перейти к определенной строке в огромном текстовом файле?, предыдущий вопрос stackoverflow.com).
Цитата о документации по python, приведенной выше:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
Измените 4
на нужный номер строки, и вы включились. Обратите внимание: 4 будет выводить пятую строку, поскольку счетчик основан на нуле.
Если файл может быть очень большим и вызвать проблемы при чтении в память, может быть хорошей идеей взять @Alok советы и использовать enumerate().
Заключить:
fileobject.readlines()
или for line in fileobject
как быстрое решение для небольших файлов.linecache
для более элегантного решения, которое будет довольно быстрым для многократного чтения многих файлов.enumerate()
для файлов, которые могут быть очень большими и не будут вписываться в память. Обратите внимание, что использование этого метода может замедляться, потому что файл читается последовательно.Быстрый и компактный подход может быть:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
он принимает любой открытый файл-подобный объект thefile
(оставляя до вызывающего абонента, должен ли он быть открыт из файла диска или через, например, сокет или другой файловый поток) и набор нулевых линейные индексы whatlines
и возвращает список с низкой площадью памяти и разумной скоростью. Если количество возвращаемых строк огромно, вы можете предпочесть генератор:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
который в основном хорош только для циклирования - обратите внимание, что единственное различие происходит от использования закругленных, а не квадратных круглых скобок в инструкции return
, что делает понимание списка и выражением генератора соответственно.
Обратите внимание, что, несмотря на упоминание "строк" и "файла", эти функции намного больше намного, они будут работать с любым итерабельным, это открытый файл или любой другой, возвращая список (или генератор) элементов на основе их прогрессивных номеров позиций. Итак, я бы предложил использовать более подходящие общие имена; -).
Чтобы предложить другое решение:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
Надеюсь, это быстро и просто:)
если вы хотите, чтобы строка 7
line = open("file.txt", "r").readlines()[7]
Для полноты, вот еще один вариант.
Начнем с определения из python docs:
slice Объект, обычно содержащий часть последовательности. Слайс создается с использованием индексной нотации, [] с двоеточиями между числами, когда дано несколько, например, в переменной_имя [1: 3: 5]. Обозначение в виде скобок (индекса) использует объекты среза внутри (или в более старых версиях __getslice __() и __setslice __()).
Хотя нотация среза напрямую не применима к итераторам, пакет itertools
содержит функцию замены:
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
Дополнительным преимуществом функции является то, что она не считывает итератор до конца. Таким образом, вы можете делать более сложные вещи:
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
И чтобы ответить на исходный вопрос:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
Чтение файлов невероятно быстро. Чтение файла размером 100 МБ занимает менее 0,1 секунды (см. мою статью Чтение и запись файлов с помощью Python). Следовательно, вы должны прочитать его полностью, а затем работать с одиночными строками.
То, что делает большинство ответов здесь, не является неправильным, но плохим стилем. Открытие файлов всегда следует выполнять с помощью with
, так как он гарантирует, что файл снова будет закрыт.
Так что вы должны сделать это так:
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
Если у вас есть большой файл и потребление памяти вызывает беспокойство, вы можете обрабатывать его построчно:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
Некоторые из них прекрасны, но это можно сделать гораздо проще:
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)
При этом будет использоваться просто нарезка списка, он загружает весь файл, но большинство систем соответствующим образом минимизирует использование памяти, это быстрее, чем большинство методов, приведенных выше, и работает с моими файлами данных 10G+. Удачи!
Вы можете выполнить вызов seek(), который позиционирует вашу головку чтения к указанному байту в файле. Это не поможет вам, если вы точно не знаете, сколько байтов (символов) записано в файле до строки, которую вы хотите прочитать. Возможно, ваш файл строго отформатирован (каждая строка - это X-число байтов?), Или вы можете подсчитать количество символов самостоятельно (не забудьте включить невидимые символы, такие как разрывы строк), если вы действительно хотите повысить скорость.
В противном случае вам нужно прочитать каждую строку до желаемой строки в соответствии с одним из многих предлагаемых здесь решений.
Как насчет этого:
>>> 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()
Если вы не возражаете импортировать, то fileinput делает именно то, что вам нужно (это вы можете прочитать номер строки текущая строка)
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
Я предпочитаю этот подход, потому что он более универсальный, т.е. вы можете использовать его в файле, на результат f.readlines()
, на объекте StringIO
, что угодно:
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']
Вот мои маленькие 2 цента, за что это стоит;)
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])
Лучшее и незначительное изменение для ответа Алока Сингхала
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()
Файловые объекты имеют метод .readlines(), который предоставит вам список содержимого файла, по одной строке для элемента списка. После этого вы можете просто использовать обычные методы наложения списков.
@OP, вы можете использовать перечисление
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]
Используя оператор with, открывается файл, печатает строки 26 и 30, затем закрывает файл. Простой!
Вы можете сделать это очень просто с помощью этого синтаксиса, который уже упоминался, но это самый простой способ сделать это:
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
Чтобы напечатать строку № 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
Оригинальный автор: Фрэнк Хофманн
Если ваш большой текстовый файл file
строго хорошо структурированная (то есть каждая строка имеет одинаковую длину l
), вы могли бы использовать для n
-th линии
with open(file) as f:
f.seek(n*l)
line = f.readline() # please notice the s at the end!
last_pos = f.tell()
Отказ от ответственности Это работает только для файлов одинаковой длины!
Для печати определенных строк в текстовом файле. Создайте список "lines2print", а затем просто напечатайте, когда перечисление находится "в" списке lines2print. Чтобы избавиться от лишних '\n', используйте line.strip() или line.strip('\n'). Мне просто нравится "понимание списка" и я стараюсь использовать, когда могу. Мне нравится метод "с" для чтения текстовых файлов, чтобы не оставлять файл открытым по любой причине.
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]
или, если список маленький, просто введите список как список в понимание.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]
Для печати нужной строки. Для печати строки выше/ниже требуемой строки.
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) т.е. dline ("путь к файлу", номер_строки, если вы хотите, чтобы верхняя строка искомой строки давала 1 для нижней -1, это необязательное значение по умолчанию будет принято 0)
Если вы хотите прочитать определенные строки, такие как строка, начинающаяся после некоторой пороговой строки, вы можете использовать следующие коды:
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()
Я думаю, что это сработает
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]