Відповіді:
Якщо файл для читання великий, і ви не хочете одразу читати весь файл у пам'яті:
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
enumerate(x)
використовує x.next
, тому йому не потрібен весь файл у пам'яті.
big file
. Петлі знадобляться роки, щоб досягти індексу
Швидка відповідь:
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()
файли, які можуть бути дуже великими і не впишуться в пам'ять. Зауважте, що використання цього методу може сповільнитись, оскільки файл читається послідовно.linecache
модуля і схоже, що він читає весь файл у пам'яті. Отже, якщо випадковий доступ важливіший за оптимізацію розміру, linecache
це найкращий метод.
linecache
тепер, здається, працює лише для вихідних файлів python
linecache.getlines('/etc/passwd')[0:4]
можете читати в першому, другому, третьому та четвертому рядках.
Швидкий та компактний підхід може бути:
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
виписці, роблячи розуміння списку та вираз генератора відповідно.
Далі зауважте, що незважаючи на згадування про "рядки" та "файл", ці функції є набагато, набагато загальнішими - вони працюватимуть на будь-якому ітерабельному, будь то відкритому файлі чи будь-якому іншому, повертаючи список (або генератор) елементів на основі їх прогресивних номерів предметів. Отже, я б запропонував використовувати більш доречні загальні назви ;-).
whatlines
повинен бути а set
, оскільки він if i in whatlines
буде виконуватись швидше за допомогою набору, а не (відсортованого) списку. Я спочатку цього не помічав, а замість цього розробив власне некрасиве рішення з відсортованим списком (де мені не довелося кожен раз сканувати список, а if i in whatlines
робить саме це), але різниця у продуктивності була незначною (з моїми даними), і це рішення набагато більш елегантне.
Ради запропонувати інше рішення:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
Сподіваюся, це швидко і просто :)
якщо ви хочете рядок 7
рядок = відкрито ("file.txt", "r"). readlines () [7]
close()
файл, відкривши його таким чином?
Для повноти тут є ще один варіант.
Почнемо з визначення з python docs :
фрагмент Об'єкт, який зазвичай містить частину послідовності. Фрагмент створюється за допомогою позначення підрядного індексу [] з двокрапками між числами, коли вказано декілька, наприклад у змінному_імені [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 +. Удачі!
Ви можете здійснити call () виклик, який позиціонує вашій голові читання вказаний байт у файлі. Це не допоможе вам, якщо ви точно не знаєте, скільки байтів (символів) записано у файл перед рядком, який ви хочете прочитати. Можливо, ваш файл суворо відформатований (у кожному рядку X кількість байтів?), Або ви можете самі порахувати кількість символів (пам’ятайте, що слід включити невидимі символи, як розриви рядків), якщо ви дійсно хочете збільшити швидкість.
В іншому випадку вам доводиться читати кожен рядок до потрібного рядка відповідно до одного з багатьох запропонованих тут рішень.
Якщо ваш великий текстовий файл file
має чітку структуру (тобто кожен рядок має однакову довжину l
), ви можете використовувати для n
-го рядка
with open(file) as f:
f.seek(n*l)
line = f.readline()
last_pos = f.tell()
Відмова від відповідальності Це працює лише для файлів однакової довжини!
Як щодо цього:
>>> 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])
Файлові об’єкти мають метод .readlines (), який надасть вам список вмісту файлу, один рядок на елемент списку. Після цього ви можете просто використовувати звичайні методи нарізки списку.
file = '/path/to/file_to_be_read.txt'
with open(file) as f:
print f.readlines()[26]
print f.readlines()[30]
Використовуючи оператор with, це відкриває файл, друкує рядки 26 і 30, а потім закриває файл. Просто!
readlines()
ітератору буде вичерпано, а другий дзвінок або поверне порожній список, або видасть помилку (не пам'ятаю, яка)
Це можна зробити дуже просто за допомогою цього синтаксису, про який вже згадував хтось, але це, безумовно, найпростіший спосіб:
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
Оригінальний автор: Frank Hofmann
Щоб надрукувати певні рядки у текстовому файлі. Створіть список "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()
виконати ----> 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]