Estoy leyendo el libro Programming Collective Intelligence, ¿qué hace exactamente el siguiente código de Python?

  # Add up the squares of all the differences 
  sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) 
                      for item in prefs[person1] if item in prefs[person2]]) 

Estoy tratando de jugar con los ejemplos en Java.

Prefs es un mapa de clasificaciones de persona a película, las clasificaciones de películas son otro mapa de nombres a clasificaciones.

0
Hamza Yerlikaya 10 nov. 2009 a las 16:45

4 respuestas

La mejor respuesta

Primero construye una lista que contiene los resultados de:

for each item in prefs for person1:
    if that is also an item in the prefs for person2:
        find the difference between the number of prefs for that item for the two people
        and square it (Math.pow(x,2) is "x squared")

Luego los suma.

6
andrew cooke 10 nov. 2009 a las 13:49
01 sum_of_squares =
02 sum(
03  [
04      pow(
05         prefs[person1][item]-prefs[person2][item],
06         2
07      ) 
08    for
09       item
10    in
11       prefs[person1]
12    if
13       item in prefs[person2]
14  ]
15 )

Suma (línea 2) una lista, que consiste en los valores calculados en las líneas 4-7 para cada 'elemento' definido en la lista especificada en la línea 11 para la cual la condición en la línea 13 es verdadera.

1
Amber 10 nov. 2009 a las 13:51

Esto podría ser un poco más legible si la llamada a pow se reemplazara con un uso explícito del operador de exponenciación '**':

sum_of_squares=sum([(prefs[person1][item]-prefs[person2][item])**2
                   for item in prefs[person1] if item in prefs[person2]])

Sacar algunos invariantes también ayuda a la legibilidad:

p1_prefs = prefs[person1]
p2_prefs = prefs[person2]

sum_of_squares=sum([(p1_prefs[item]-p2_prefs[item])**2
                      for item in p1_prefs if item in p2_prefs])

Finalmente, en versiones recientes de Python, no hay necesidad de la notación de comprensión de la lista, sum aceptará una expresión generadora, por lo que los [] 's también se pueden eliminar:

sum_of_squares=sum((p1_prefs[item]-p2_prefs[item])**2
                      for item in p1_prefs if item in p2_prefs)

Parece un poco más sencilla ahora.

Irónicamente, en pos de la legibilidad, también hemos realizado una optimización del rendimiento (dos esfuerzos que generalmente son mutuamente excluyentes):

  • invariantes levantados fuera del circuito
  • reemplazó la función call pow con evaluación en línea del operador '**'
  • eliminó la construcción innecesaria de una lista

¿Es este un gran idioma o qué?

2
PaulMcG 10 nov. 2009 a las 18:16

Calcula la suma de los cuadrados de la diferencia entre prefs[person1][item] y prefs[person2][item], por cada item en el diccionario prefs para person1 que también está en el { Diccionario {X5}} para person2.

En otras palabras, digamos que tanto person1 como person2 tienen una calificación para la película Ratatouille, con person1 calificándolo con 5 estrellas y person2 calificándolo con 2 estrellas.

prefs[person1]['Ratatouille'] = 5
prefs[person2]['Ratatouille'] = 2

El cuadrado de la diferencia entre la calificación de person1 y la calificación de person2 es 3^2 = 9.

Probablemente esté computando algún tipo de Variance.

0
Dominic Rodger 10 nov. 2009 a las 13:49