Sum of Integer Numbers in a txt File

0

I have two txt files that contain only numbers (number per line), so I want to add line 1 + line 1 so in succession to the last line of each file. Each file has the same line number.

** In this code I can only print the first sum of the first line **

arq = open ("Lista1.txt")
arq2 = open ("Lista2.txt")
x = [linha.strip() for linha in arq]
arq.close()
y = [linha.strip() for linha in arq2]
arq2.close()


for linha in x:
   indice = 0
   while indice<len(x):
     soma = (int(x[indice]) + int(y[indice]))
     indice+=1
   print soma
    
asked by anonymous 18.02.2018 / 17:23

2 answers

-1

Speak Jeferson, all right?

Knowing that the two files would always be the same size, you can iterate under range of size ( len ) of the previously read list, for example the y list. It looks like this:

arq = open ("txt1.txt")
arq2 = open ("txt2.txt")
x = arq.readlines()  #[linha.strip() for linha in arq]
arq.close()
y = arq2.readlines() #[linha.strip() for linha in arq2]
arq2.close()
novalista = [] #caso queira adicionar as somas em uma lista 

for i in range(len(y)):
    soma = int(x[i]) + int(y[i])
    novalista.append(soma) #adiciona somas na lista 
    print(soma) #imprime as somas individuais
#print(novalista)

So you do not need to use while within for to limit the iteration to the file size.

I've also used the readlines() function, it already returns a list considering the txt line breaks as divisions.

Thank you.

    
18.02.2018 / 22:11
0

While the workaround presented may yield the expected result, it is far from being idiomatic , although I believe you have been useful to compare with the code presented in the question and aided in identifying errors. So, I propose a slightly more elegant solution for the language in question:

with open("numbers_1.txt") as numbers_1, open("numbers_2.txt") as numbers_2:
    for pair in zip(numbers_1, numbers_2):
        print(sum(map(int, pair)))

See working at Repl.it

With with I open both files in read mode, instantiating the two generators responsible for each file , numbers_1 and numbers_2 , respectively. After, iterates with a for loop over the result of zip() , which makes the association between the elements of the two generators: the nth term of numbers_1 is associated with the nth term of numbers_2 in a tuple, where n ranges from 0 to the length of the sequence one less). Then, I display the result of the sum, through the sum() function, which receives an iterable for converting the values of the pair into integer values.

In a way, the code can still be improved by building a generator from this structure:

def sum_of_files(file_1, file_2):
    with open(file_1) as numbers_1, open(file_2) as numbers_2:
        for pair in zip(numbers_1, numbers_2):
            yield sum(map(int, pair))

for s in sum_of_files('numbers_1.txt', 'numbers_2.txt'):
    print(s)

See working at Repl.it

The advantage of this second solution is that you do not need to keep the stored value sequence stored in memory at all, which greatly optimizes if your files grow spontaneously, reaching thousands of lines or more. The first solution would have the final sequence stored in memory (assuming no print was used) and the solution of the other response would have three times the stored sequence (it demands a lot more resources).

You can further improve the code by breaking the limitation of only two files, allowing as many files as needed:

def sum_of_files(*files):
    streams = map(open, files)
    for numbers in zip(*streams):
        yield sum(map(int, numbers))
    for stream in streams:
        stream.close()

for s in sum_of_files('numbers_1.txt', 'numbers_2.txt', 'numbers_3.txt'):
    print(s)

See working at Repl.it

And it's still possible to improve by breaking the limitation that files need to be the same size by replacing the zip() function with the itertools.zip_longest() function:

from itertools import zip_longest

def sum_of_files(*files):
    streams = map(open, files)
    for numbers in zip_longest(*streams, fillvalue=0):
        yield sum(map(int, numbers))
    for stream in streams:
        stream.close()

for s in sum_of_files('numbers_1.txt', 'numbers_2.txt', 'numbers_3.txt'):
    print(s)

See working at Repl.it

Smaller files, which do not have the complete sequence of values, will have their numbers equal to 0 because of the fillvalue parameter. This way, you will be able to add as many files as you need, regardless of the size of each one, provided they have valid values, without having to store the sequence, being the code very efficient even for files with millions of lines.

    
20.02.2018 / 02:49