Quiero encontrar una lista de elementos en un archivo en un índice específico.

Por ejemplo, a continuación se encuentran los contenidos del archivo "temp.txt"

line_0 1
line_1 2
line_2 3
line_3 4
line_4 1
line_5 1
line_6 2
line_7 1
line_8 2
line_9 3
line_10 4

Ahora, necesito encontrar la lista de valores [1,2,3] que ocurren en secuencia en la columna 2 de cada línea en el archivo anterior.

La salida debería verse a continuación:

line_2 3
line_9 3

He intentado la siguiente lógica, pero de alguna manera no funciona; (

   inf = open("temp.txt", "rt")
   count = 0
   pos = 0
   ListSeq = ["1","2","3"]
   for line_no, line in enumerate(inf):
      arr = line.split()
      if len(arr) > 1:
         if count == 1 :
            pos = line_no
         if ListSeq[count] == arr[1] :
            count += 1
         elif count > 0 :
            inf.seek(pos)
            line_no = pos
            count = 0
         else :
            count = 0            
      if count >= 3 :
         print(line)
         count = 0

¿Alguien puede ayudarme a encontrar el problema con el código anterior? o incluso una lógica diferente que dará una salida correcta también está bien.

1
Bharath 15 feb. 2017 a las 13:19

2 respuestas

La mejor respuesta

Tu código es defectuoso. El error más destacado: intentar seek en un archivo de texto usando el número de línea nunca va a funcionar: para eso debes usar el desplazamiento de bytes. Incluso si hiciera eso, sería incorrecto porque está iterando en las líneas, por lo que no debe intentar cambiar el puntero del archivo mientras lo hace.

Mi enfoque:

La idea es "transponer" su archivo para trabajar con vectores verticales, encontrar la secuencia en el segundo vector vertical y utilizar el índice encontrado para extraer datos en el primer vector vertical.

split líneas para obtener texto y número, comprima los resultados para obtener 2 vectores: 1 de números 1 de texto.

En este punto, una lista contiene ["line_0","line_1",...] y la otra contiene ["1","2","3","4",...]

Encuentre los índices de la secuencia en la lista de números e imprima el par txt / número cuando lo encuentre.

Código:

with open("text.txt") as f:
    sequence = ('1','2','3')
    txt,nums = list(zip(*(l.split()[:2] for l in f)))  # [:2] in case there are more columns
    for i in range(len(nums)-len(sequence)+1):
        if nums[i:i+len(sequence)]==sequence:
            print("{} {}".format(txt[i+2],nums[i+2]))

Resultado:

line_2 3
line_9 3

El último bucle for se puede reemplazar por una comprensión de la lista para generar las tuplas:

result = [(txt[i+2],nums[i+2]) for i in range(len(nums)-len(sequence)) if nums[i:i+len(sequence)]==sequence ]

Resultado:

[('line_2', '3'), ('line_9', '3')]
1
Jean-François Fabre 15 feb. 2017 a las 13:55

Generalizando para cualquier secuencia y cualquier columna.

sequence = ['1','2','3']
col = 1

with open(filename, 'r') as infile:
    idx = 0
    for _i, line in enumerate(infile):
        if line.strip().split()[col] == sequence[idx]:
            if idx == len(sequence)-1:
                print(line)
                idx = 0
            else:
                idx += 1
        else:
            idx = 0
1
Matt Fortier 15 feb. 2017 a las 11:39