The method sort
, class list
, when used with the parameter key
will execute the sort as the value returned by the expression defined in key
, not the value present in the list itself. For your case, it is used:
key=lambda p: (p.x, py. p.z)
That is, the expression that will be used will be a lambda expression that will convert an object of type Ponto
in a tuple with the corresponding coordinates of the point. Natively, in Python, when comparing two tuples, the comparison gives value to value, from left to right, i.e., compares x, then y and finally z.
Therefore, considering a short list of points:
lista = [Ponto(x=1,y=2,z=3), Ponto(x=2,y=3,z=2), Ponto(x=2,y=2,z=2)]
When executing the sort function:
lista.sort(key=lambda p: (p.x, p.y, p.z))
Roughly speaking, what happens is:
- Sets an auxiliary list with the first value of the list:
saida = [Ponto(x=1,y=2,z=3)]
;
- Takes the second value of the list, iterates over the auxiliary list and applies the lambda expression both in the value to be added and in the value present in the auxiliary list, comparing its returns:
- The return of the lambda expression to the value to be added will be:
(2, 3, 2)
;
- Scroll through the auxiliary list and the return of the expression to the value in the auxiliary list will be:
(1, 2, 3)
;
- Compare the two tuples returned and, as the tuple of the value to be added will be after the tuple returned to the value in the auxiliary list, the value is inserted after;
- The auxiliary list is then:
saida = [Ponto(x=1,y=2,z=3), Ponto(x=2,y=3,z=2)]
;
- Take the third value from the list and repeat the process:
- The return of the lambda expression of the first value of the auxiliary list will be:
(1, 2, 3)
;
- The return of the lambda expression to the added value will be:
(2, 2, 2)
;
- Comparing them, it is verified that the new value must be added after the first;
- Then the same comparison is made with the second value:
- The lambda expression return of the second value of the auxiliary list will be:
(2, 3, 2)
;
- Comparing them, it turns out that the new value should be inserted before the second;
- Thus, the new value is inserted in the auxiliary list between the first and the second value, leaving:
saida = [Ponto(x=1,y=2,z=3), Ponto(x=2,y=2,z=2), Ponto(x=2,y=3,z=2)]
;
- After iterations, the new list value is defined as the auxiliary list:
lista = saida
;
This way, after ordering, the list would be:
lista = [Ponto(x=1,y=2,z=3), Ponto(x=2,y=2,z=2), Ponto(x=2,y=3,z=2)]
Ordered according to the values of x, y and z, respectively. Function performance is not greatly affected by the use of the parameter key
because, due to internal language implementations, the expression defined in key
is called only once for each value in the list, regardless of how often this value is used in the sorting process.
Very good class design
Ponto
to have a minimal, simple and complete example– Jefferson Quesado