Lectura de líneas específicas solamente

Estoy usando un bucle for para leer un archivo, pero solo quiero leer líneas específicas, por ejemplo, las líneas 26 y 30. ¿Hay alguna característica incorporada para lograr esto?

Gracias

Si el archivo para leer es grande y no desea leer todo el archivo en la memoria de una vez:

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() 

Tenga en cuenta que i == n-1 para la línea n .


En Python 2.6 o posterior:

 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 

La respuesta rápida:

 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 

Hay una solución más elegante para extraer muchas líneas: linecache (cortesía de “python: ¿cómo saltar a una línea en particular en un archivo de texto enorme?” , Una pregunta anterior de stackoverflow.com).

Citando la documentación de python enlazada arriba:

 >>> import linecache >>> linecache.getline('/etc/passwd', 4) 'sys:x:3:3:sys:/dev:/bin/sh\n' 

Cambie el 4 a su número de línea deseado, y ya está. Tenga en cuenta que 4 traería la quinta línea ya que el conteo se basa en cero.

Si el archivo puede ser muy grande y causar problemas al leerlo en la memoria, podría ser una buena idea seguir los consejos de @Alok y usar enumerate () .

Para concluir:

  • Utilice fileobject.readlines() o for line in fileobject como una solución rápida para archivos pequeños.
  • Utilice linecache para una solución más elegante, que será bastante rápida para leer muchos archivos, posible repetidamente.
  • Tome el consejo de @Alok y use enumerate() para archivos que podrían ser muy grandes y que no caben en la memoria. Tenga en cuenta que el uso de este método puede ralentizarse porque el archivo se lee secuencialmente.

Un enfoque rápido y compacto podría ser:

 def picklines(thefile, whatlines): return [x for i, x in enumerate(thefile) if i in whatlines] 

este acepta cualquier objeto abierto similar a un archivo thefile (que se deja a la persona que llama si debe abrirse desde un archivo de disco, o por ejemplo a través de un socket u otra secuencia similar a un archivo) y un conjunto de índices de líneas basados ​​en whatlines , y devuelve una lista, con poca huella de memoria y velocidad razonable. Si el número de líneas a devolver es enorme, es posible que prefiera un generador:

 def yieldlines(thefile, whatlines): return (x for i, x in enumerate(thefile) if i in whatlines) 

lo que básicamente es bueno solo para realizar un bucle, tenga en cuenta que la única diferencia proviene del uso de paréntesis redondeados en lugar de cuadrados en la statement de return , haciendo una lista de comprensión y una expresión generadora respectivamente.

Además, tenga en cuenta que, a pesar de la mención de “líneas” y “archivo”, estas funciones son mucho más generales: funcionarán en cualquier iterable, ya sea un archivo abierto o cualquier otro, devolviendo una lista (o generador) de elementos. Basado en sus números de artículo progresivos. Por lo tanto, sugeriría usar nombres más apropiados en general ;-).

Por el bien de ofrecer otra solución:

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

Espero que esto sea rápido y fácil 🙂

si quieres linea 7

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

Por el bien de la integridad, aquí hay una opción más.

Comencemos con una definición de los documentos de python :

rebanada Un objeto que normalmente contiene una parte de una secuencia. Una porción se crea utilizando la notación de subíndices, [] con dos puntos entre los números cuando se dan varios, como en variable_name [1: 3: 5]. La notación de corchete (subíndice) utiliza objetos de división internamente (o en versiones anteriores, __getslice __ () y __setslice __ ()).

Aunque la notación de itertools no es directamente aplicable a los iteradores en general, el paquete itertools contiene una función de reemplazo:

 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 

La ventaja adicional de la función es que no lee el iterador hasta el final. Para que puedas hacer cosas más complejas:

 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 

Y para responder a la pregunta original:

 # how to read lines #26 and #30 In [365]: list(islice(xrange(1,100), 25, 30, 4)) Out[365]: [26, 30] 

Leer archivos es increiblemente rápido. Leer un archivo de 100MB toma menos de 0.1 segundos (vea mi artículo Leer y escribir archivos con Python ). Por lo tanto, debes leerlo completamente y luego trabajar con las líneas simples.

Lo que la mayoría de las respuestas aquí hacen no es incorrecto, sino mal estilo. La apertura de los archivos siempre debe hacerse con ellos, ya que se asegura de que el archivo se cierre de nuevo.

Así que deberías hacerlo así:

 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 

Archivos enormes

Si tienes un gran archivo y el consumo de memoria es una preocupación, puedes procesarlo línea por línea:

 with open("path/to/file.txt") as f: for i, line in enumerate(f): pass # process line i 

Algunos de estos son encantadores, pero se pueden hacer mucho más simplemente:

 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) 

Eso usará simplemente el corte de la lista, cargará todo el archivo, pero la mayoría de los sistemas minimizarán el uso de la memoria adecuadamente, es más rápido que la mayoría de los métodos dados anteriormente y funciona en mis archivos de datos 10G +. ¡Buena suerte!

Puede hacer una llamada search () que posiciona su cabeza de lectura a un byte específico dentro del archivo. Esto no le ayudará a menos que sepa exactamente cuántos bytes (caracteres) se escriben en el archivo antes de la línea que desea leer. Tal vez su archivo tenga un formato estricto (¿cada línea es X número de bytes?) O, podría contar el número de caracteres (recuerde incluir caracteres invisibles como saltos de línea) si realmente desea boost la velocidad.

De lo contrario, tiene que leer cada línea antes de la línea que desea, según una de las muchas soluciones que ya se han propuesto aquí.

Qué tal esto:

 >>> 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() 

Si no te importa importar, fileinput hace exactamente lo que necesitas (esto es, puedes leer el número de línea de la línea actual)

 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 

Prefiero este enfoque porque es de propósito más general, es decir, puede usarlo en un archivo, en el resultado de f.readlines() , en un objeto StringIO , lo que sea:

 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'] 

Aquí está mi pequeño 2 centavos, por lo que 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]) 

Un cambio mejor y menor para la respuesta de Alok Singhal.

 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() 

Los objetos de archivo tienen un método .readlines () que le dará una lista de los contenidos del archivo, una línea por elemento de lista. Después de eso, puedes usar técnicas de corte de listas normales.

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

@OP, puedes usar enumerar

 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 la instrucción with, esto abre el archivo, imprime las líneas 26 y 30, luego cierra el archivo. ¡Sencillo!

Puedes hacer esto de manera muy simple con esta syntax que alguien ya mencionó, pero es la forma más fácil de hacerlo:

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

Para imprimir la línea # 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 

Autor original: Frank Hofmann

Si su archivo de texto grande está estrictamente bien estructurado (lo que significa que cada línea tiene la misma longitud l ), podría usar para la línea 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() 

Descargo de responsabilidad ¡ Esto solo funciona para archivos con la misma longitud!

Para imprimir la linea deseada. Para imprimir la línea arriba / debajo de la línea requerida.

 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() 

ejecute —-> dline (“D: \ dummy.txt”, 6) es decir, dline (“ruta de archivo”, número de línea, si desea que la línea superior de la línea buscada proporcione 1 para menor -1, este es el valor predeterminado opcional) ser tomado 0)

Bastante rápido y al punto.

Para imprimir ciertas líneas en un archivo de texto. Cree una lista “lines2print” y luego imprímala cuando la enumeración esté “en” la lista lines2print. Para deshacerte de ‘\ n’ extra usa line.strip () o line.strip (‘\ n’). Simplemente me gusta “comprensión de lista” y trato de usar cuando puedo. Me gusta el método “con” para leer archivos de texto para evitar dejar un archivo abierto por cualquier 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 si la lista es pequeña, simplemente escriba en lista como una lista en la comprensión.

 with open("filepath", 'r') as fp: [print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]] 
 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() 

Creo que esto funcionaria

  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]