Sum of Integer Numbers in a txt File

Asked

Viewed 1,542 times

0

I have two txt files that contain only numbers (number per line), so I want to add line 1 + line 1 so successively until 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

2 answers

0


It’s Jeferson, all right?

Knowing that the two files would always be the same size, you can iterate under the range of size(len) from the list previously read, for example the list y. Being as follows:

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 don’t need to use one while within the for to limit iteration to file size.

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

Hug.

  • Thanks for the help. ^^

0

Although the solution presented may generate the expected result, it is far from being idiomatic, although I believe it was useful to compare with the code presented in the question and help identify the errors. I therefore 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 on Repl.it

With the with open both files in read mode, instantiating the two generators responsible for each file, numbers_1 and numbers_2, respectively. After, itero with a loop for on the outcome 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 varies from 0 to the length of the sequence (minus one). Then display the sum result, through the function sum(), which receives an iterable which is responsible 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 on Repl.it

The advantage of this second solution is that you do not need to, at any time, keep the sequence of values stored completely in memory, which greatly optimizes if your files grow spontaneously, and can reach thousands of lines or more. The first solution would have the final sequence stored in the memory (considering that the print) and the solution of the other answer would have three times the stored sequence (demand much more resources).

It is even possible to improve the code by breaking the limitation of only two files, allowing as many files are 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 on Repl.it

And yet it is possible to improve by breaking the limitation that files need to be of the same size by overwriting the function zip() by function itertools.zip_longest():

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 on Repl.it

Smaller files, which do not have the full sequence of values, will have their numbers equal to 0 due to the parameter fillvalue. This way, you will be able to sum up as many files as necessary, regardless of the size of each one, as long as they have valid values, without having to store the sequence in memory, and the code is very efficient even for files with millions of lines.

  • Good Anderson, thanks for the reply, taught me a lot too, ball show. Hug!!!

Browser other questions tagged

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