Consulting previous index in Python

Asked

Viewed 95 times

2

That question is a continuation of this here

As previously reported, I have a script that does a txt search for a keyword (APPLE) and if it is true, it alters another part ("00" or "01" or "02") of that same TXT, to illustrate, I will follow with these three lines:

123456 BANANA 00 SP
123457 MACA 01 RJ
123458 PERA 02 MG

It turns out that these three lines are part of the same "header".

The code that is already doing this is this (the number of positions does not reflect with reality, it is only an example, but in the real file they have a layout):

import shutil, tempfile

# lê do arquivo e escreve em outro arquivo temporário
with open('teste.txt', 'r') as arquivo, \
     tempfile.NamedTemporaryFile('w', delete=False) as out:
    for linha in arquivo:
        codigo = linha[07:14] #PESQUISA POR MAÇÃ
        
        if codigo == 'MACA':
           print("ACHOU, CODIGO: " + codigo)
           linha = linha[:14] + "22" + linha[16:] # remontar a linha com a alteração
        else:
           print("NÃO ACHOU, CÓDIGO: " + codigo)

        out.write(linha) # escreve no arquivo temporário

# move o arquivo temporário para o original
shutil.move(out.name, 'teste.txt')

But there is a problem of logic in this solution, because my reality is that second line i find the "APPLE", I will not change the same line, and yes to top line, that belongs to "BANANA" and that my code has already passed. So the result I hope if the script ends is:

123456 BANANA 22 SP
123457 MACA 01 RJ
123458 PERA 02 MG

UPDATE

The solution I followed then was: create a list and keep adding my lines in it, so I can return a position if necessary, and it was more or less like this:

import shutil, tempfile
saida = []
# lê do arquivo e escreve em outro arquivo temporário
with open('teste.txt', 'r') as arquivo, \
 tempfile.NamedTemporaryFile('w', delete=False) as out:
  for i,linha in enumerate(arquivo):
  saida.append(linha)
  saidaLinha = saida[i]
  codigo = linha[07:14]
  if codigo == 'MACA':
   print("ACHOU, CODIGO: " + codigo)
   saidaLinha = saida[i-1][:14] + "22" + saida[i-1][16:]
   out.write(saidaLinha)
   print('linha alterada: '+saidaLinha)
 else:
 print("NÃO ACHOU, CÓDIGO: " + codigo)
out.write(linha)
# move o arquivo temporário para o original
shutil.move(out.name, 'teste.txt')

However, my output is repeating the first line without ever changing, for example like this:

123456 BANANA 01 SP 123456 BANANA 22 SP 123457 MACA 01 RJ 123458 PERA 02 MG

Does anyone know how to fix this part?

  • So man, first you need to fix your code indentation. In Python when indentation is wrong, strange things happen. Also note that you keep calling out.write in all iterations. Thus, the list is useless saida, because at the end you are not writing it. Do not write in the output file inside the main loop. First you write in saida, and after the main loop you write all the content of saida in your file.

  • How to correctly identify: https://pt.wikibooks.org/wiki/Python/Conceitos_b%C3%A1sicos/Indenta%C3%A7%C3%A3o

1 answer

2

I recommend you store all outputs you write in a list of strings. Then, when you need to modify the previous one, just modify it in the list. At the end you write the contents of the whole list. The function enumerate also helps, because with it you can go through an eternal with reference to both the index and its values.

import shutil, tempfile
out = []

# lê do arquivo e escreve em outro arquivo temporário
with open('teste.txt', 'r') as arquivo:
    for i, linha in enumerate(arquivo):
        codigo = linha[07:14] #PESQUISA POR MAÇÃ
        
        if codigo == 'MACA':
           print("ACHOU, CODIGO: " + codigo)
           linha = linha[:14] + "22" + linha[16:] # remontar a linha com a alteração
        else:
           print("NÃO ACHOU, CÓDIGO: " + codigo)

        out.append(linha)

with open('teste.txt', 'w') as saida:
    saida.writelines(out)

If something has not become clear enough, please comment, I will try to improve.

  • Sorry, I didn’t quite understand what I would attribute exit[i - 1]... I understand that I am creating a list where each line will be an index... but this part I was confused

  • So dude, I edited it out, I think it’s clearer now. I took your code and I tweaked a little bit, the difference is now out is a list of strings. At the end, you will take this list of strings and write to your file. i, when you want to look at the previous line just access out[i - 1] and make the necessary modifications. If still not clear enough do not hesitate to ask, thanks!!

  • This code is giving error Allan! But I understood what you meant, I still get a little confused on what I will call the Oct[i - 1], would be something like line = out[i - 1]?

  • Good solution. The code contains errors, one of them is out variable which is reassigned to Namedtemporaryfile.

  • I removed the re-distribution, I hadn’t seen it. Thanks Pablo. So Luiz, to access the contents of the line before you are, just do out[i - 1] same. If you want to do an experiment can printar linha and out[i - 1] with each iteration, it will certainly help you better understand how the loop is working.

  • Allan, I managed to advance, but my code is repeating the first line,?

  • How so repeating the line? Edit your post with the new code and describe in detail the behavior you are getting.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.