0

Here is the problem I'm struggling with: Two files named numbers1.txt and numbers2.txt both have an unknown number of lines, each line consisting of a single positive integer. Write some code that reads a line from one file and then a line from the other file. The two integers are multiplied together and their product is added to a variable called scalar_product which should be initialized to zero.

Your code should stop when it detects end of file in either file that it is reading.

For example, if the sequence of integers in one file was "9 7 5 18 13 2 22 16" and "4 7 8 2" in the other file, your code would compute:

4*9 + 7*7 + 8*5 + 2*18

and thus store 161 into scalar_product.

Current code:

number1 = open('numbers1.txt', 'r')
number2 = open('numbers2.txt', 'r')
scalar_product = 0
while number1.readline() != '' and number2.readline() != '':
product = int(number1.readline()) * int(number2.readline())
scalar_product += product
number1.close
number2.close

2 Answers 2

3

It's much easier than you're making it, even without getting overly clever:

from future_builtins import zip  # Use this on Py2 to avoid intermediate lists

scalar_product = 0
with open('numbers1.txt') as n1, open('numbers2.txt') as n2:
    for line1, line2 in zip(n1, n2):
        scalar_product += int(line1) * int(line2)

The zip function is key; it reads each iterator in parallel, returning a value from each, stopping when one iterator is exhausted. Files iterate by line, and int apparently doesn't care about surrounding whitespace (so the new lines are fine).

Getting slightly more clever, you can push all the work to the C layer (in CPython) to get optimum performance by doing:

from future_builtins import map  # Use this on Py2 to avoid intermediate lists
from operator import mul

with open('numbers1.txt') as n1, open('numbers2.txt') as n2:
    n1 = map(int, n1)
    n2 = map(int, n2)
    scalar_product = sum(map(mul, n1, n2))
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks so much! Just for future use, if anyone does this problem, just change the '+' to '*' and you're good to go!
@ryanturf: Fixed already. Someone else made the edit, accidentally stomped it while adding additional info (I readded it when I realized).
Actually, .rstrip() is unnecessary; int() ignores whitespace including newlines.
@HughBothwell: Huh, what do you know? I've been using Python for years and just assumed it would be more pedantic about that. Updated.
0

I understand this is a bit older, but here's another method that didn't require importing the zip function:

num1 = open('numbers1.txt', 'r')
num2 = open('numbers2.txt', 'r')
scalar_product = 0

num1line = num1.readline()
num2line = num2.readline()

while num1line != '' and num2line != '':
    num1line = int(num1line)
    num2line = int(num2line)
    scalar_product += (num1line * num2line)
    num1line = num1.readline()
    num2line = num2.readline()

The while loop checks to see if either file is empty and is advanced to the next line of each file only if both files have more lines. For each index position of the file, it converts the returned string stored in num1line or num2line to a string, multiplies those values, and adds the total to scalar_product. I hope this helps someone!

1 Comment

You don't actually need to import zip. It's a built-in, it's just that it operates eagerly on Python 2, so on Python 2, it's usually more efficient to import the Python 3 version (which operates lazily; it returns an iterator, not a new list). The import is mostly for consistent behavior/performance on either version, but it will work without the import either way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.