Difference between creating a list with each iteration and using a list comprehension

Asked

Viewed 95 times

3

I need to calculate the distance between the points (0,0) and (1,1). For that, I wrote the following code:

def distance(x, y):
   if len(x) != len(y):
       return "x and y não possuem o mesmo comprimento"
   else:
       for i in range(len(x)):
           square_differences = [(x[i] - y[i])**2]
       return math.sqrt(sum(square_differences))

print(distance((0,0),(1,1)))

However, always when I run I get an error. However, if I change the position of the for thus:

def distance(x, y):
   if len(x) != len(y):
       return "x and y não possuem o mesmo comprimento"
   else:
       square_differences = [(x[i] - y[i])**2 for i in range(len(x))]
       return math.sqrt(sum(square_differences))

print(distance((0,0),(1,1)))

I get the correct answer. Could someone explain to me why?

  • From what I understand the program only makes the operation "square_differences" once. I don’t know why.

3 answers

4


When you do:

square_differences = [(x[i] - y[i])**2]

You are creating a list containing a single element: the result of (x[i] - y[i])**2.

And every iteration of for, you are overwriting the value of square_differences. That is, at the end of the loop, that variable will only have a list containing a single element, which is the result of the account in question (for i equal to 1). The previous result (for i equal to zero) is discarded.

Already when you do:

square_differences = [(x[i] - y[i])**2 for i in range(len(x))]

Is using a comprehensilist on, which is essentially a more succinct and pythonic to make a loop. The line above is equivalent to:

square_differences = []
for i in range(len(x)):
    square_differences.append((x[i] - y[i])**2)

That is, both are ways to create a list containing the results of operations. At the end, the list will have 2 elements (and not just one): the results of the square of the difference between the respective elements of x and y.


For the record, another way would be:

def distance(x, y):
    if len(x) != len(y):
        raise ValueError("x and y não possuem o mesmo comprimento")
    return math.sqrt(sum((ex - ey) ** 2 for ex, ey in zip(x, y)))

The sum can be made at once, just using zip to scroll through both tuples at the same time: with each iteration, ex will be an element of x, and ey will be an element of y. The zip terminates when the shortest of lists/tuples/eternal ends, but as you check before if both are the same size, there will be no problem using it here.

And instead of the function returning a number or a string, depending on the case, I made it throw an exception in case of invalid values. Thus, it would be enough to capture the exception to know if there was a mistake:

try:
    print(distance((0, 1, 2), (1, 1)))
except ValueError as e:
    print('Erro:', e) # Erro: x and y não possuem o mesmo comprimento

Also note that the else is unnecessary. If x and y have different lengths, it enters the if and throws the exception, interrupting the execution of the function. If the lengths are equal, it does not enter the if and performs the calculations, returning the result.

0

Looking over it, its first function stores a unique value in its square_differences variable at the end of the loop. The second stores an array. For the first one to work you would have to declare the array out of the loop and use the append() method. I hope I helped.

  • Thanks, I get it now.

0

If you just want to calculate the distance between two points, you can use the following algorithm...

from math import sqrt

p = list(map(int, input('Digite as coordenadas dos pontos: ').split()))
distancia = sqrt(pow((p[2] - p[0]), 2) + pow((p[3] - p[1]), 2))
print('A distancia entre os pontos é: {:.2f}'.format(distancia))

In this algorithm "p" is a list that will store the value of the coordinates of the points. To correctly use this algorithm you must enter the value of the coordinates in the same line of the console, separating them by a space. Example: If you want to calculate the distance between points (0, 0) and (1, 1), you must run the program and enter the coordinates "X1", space, "Y1", space, "X2", space and "Y2", that is to say...

Digite as coordenadas dos pontos: 0 0 1 1

Then press "Enter" to get the result. The result will be printed as follows...

A distancia entre os pontos é: 1.41

Note that the distance is being calculated to two decimal places.

Browser other questions tagged

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