Чтение только определенных строк (Python)



Я использую цикл for для чтения файла, но я хочу читать только определенные строки, скажем, строки #26 и #30. Есть ли встроенная функция для этого?



спасибо

1116   24  

24 ответов:

если файл большой, и вы не хотите читать весь файл в память сразу:

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 принесет пятый строка в качестве счетчика основана на нуле.

если файл может быть очень большим, и вызвать проблемы при чтении в память, это может быть хорошей идеей, чтобы взять @Алок и использовать перечисления().

В Заключение:

  • использовать 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 заявление, делая понимание списка и выражение генератора соответственно.

далее отметим, что несмотря на упоминание "строк" и "файлов" этих функций очень много, много более общие -- они будут работать на любой iterable, будь то открытый файл или любой другой, возвращающий список (или генератор) элементов на основе их прогрессивного номер позиции. Поэтому я бы предложил использовать более подходящие общие имена; -).

ради предложения другого решения:

import linecache
linecache.getline('Sample.txt', Number_of_Line)

Я надеюсь, что это быстро и легко :)

Если вы хотите, чтобы строка 7

line = open("file.txt", "r").readlines()[7]

для полноты картины, вот еще один вариант.

давайте начнем с определения от python docs:

slice объект, обычно содержащий часть последовательности. Срез создается с использованием нотации подстрочного индекса, [] с двоеточиями между числами, когда несколько заданы, например, в variable_name[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]

некоторые из них прекрасны, но это можно сделать гораздо проще:

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+ файлов данных. Удачи вам!

чтение файлов невероятно быстро. Чтение 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

можно сделать 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

вот мои маленькие 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()

файловые объекты имеют a .readlines() метод, который даст вам список содержимого файла, по одной строке на элемент списка. После этого вы можете просто использовать обычные методы нарезки списка.

http://docs.python.org/library/stdtypes.html#file.readlines

Я предпочитаю такой подход, потому что он более универсальный, т. е. вы можете использовать его на файл, на результат f.readlines() на

@OP, вы можете использовать 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]

С помощью оператора with, это открывает файл, печатает строки 26 и 30, а затем закрывает файл. Просто!

для печати строки# 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

Автор оригинала: Франк Хофманн

вы можете сделать это очень просто с таким синтаксисом, что кто-то уже упоминал, но это, безусловно, самый простой способ сделать это:

inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])

для печати нужной строки. Для печати строки выше / ниже требуется строка.

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 ("путь к файлу", line_number, если вы хотите верхнюю строку искомой строки дать 1 для нижнего -1 это необязательное значение по умолчанию будет принято 0)

если ваш большой текстовый файл file строго хорошо структурирована (то есть каждая строка имеет одинаковую длину l), вы могли бы использовать для n-ой строке

with open(file) as f:
    f.seek(n*l)
    line = f.readline()  # please notice the s at the end!
    last_pos = f.tell()

отказ от ответственности это работает только для файлов с одинаковой длины!

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]

Comments

    Ничего не найдено.