我在学习协同过滤,遇到这样一段代码
def sim_distance(prefs,person1,person2):
# Get the list of shared_items
si={}
for item in prefs[person1]:
if item in prefs[person2]: si[item]=1
# if they have no ratings in common, return 0
if len(si)==0: return 0
# 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]])
return 1/(1+sum_of_squares)
比较困惑的是下面这段代码,为什么sum里面可以写for 循环呢,这个是什么意思,为什么我写了个类似的函数就会报错
sum([pow(prefs[person1][item]-prefs[person2][item],2)
for item in prefs[person1] if item in prefs[person2]])
Le premier paramètre accepté par sum est un itérable. Si vous voulez connaître la signification de cette boucle for, vous devez vérifier le générateur et le sucre syntaxique lié au générateur. Voici un exemple simple pour l'affiche
.[i for i in range(5)] # 结果为[0,1,2,3,4]
Le
for
ouif
ici n'ont rien à voir avecsum
lui-même. Comme @大quail l'a dit,sum
accepte un objet itérable comme paramètre Quant à l'itérable dans cet exemple, l'objet est simplement. une liste générée en utilisant la compréhension de liste.Présentons brièvement la compréhension de liste (production en série).
programmation fonctionnelle, intuitive et élégante.
Comme son nom l'indique, il sert à générer desséries.
Il y a donc un principe important :Jetons un coup d'œil à l'utilisation. C'est très simple Pour générer une liste, nous utilisons littéralement deux paires de crochets
(la syntaxe de génération littérale de liste), prenant en sandwich une itération
Regardons un exemple. Supposons qu'aujourd'hui nous ayons une liste d'entiers[]
, The. les éléments visités à l'aide defor...in...
seront utilisés pour créer chaque élément de la liste dans l'ordre.for
et que nous voulions créer une autre liste
Nous avons utilisé une bouclelst
dans laquelle chaque élément est le carré de l'élément danslst2
:lst
standard pour ce faire, mais la même chose peut être faite de manière plus concise et élégante en utilisant la
Dans cet exemple,for...in...
compréhension de liste :supprimera séquentiellement les éléments de
for i in lst
et effectuera une opération carrée pour devenir le nouvel élément delst
. Cela rappelle la fonctionlst2
, on peut aussi utiliser lemap
mapping pour obtenir des effets similaires :visitera les éléments de son deuxième paramètre (un objet itérable) dans l'ordre et utilisera l'élément comme paramètre pour appeler son premier paramètre (une fonction à paramètre unique), c'est-à-dire qu'il retirera séquentiellement 1, 2, 3, 4 et utilisez-les comme paramètres
Mais nous pouvons constater que la compréhension de liste est plus intuitive, et nous pouvons dire que l'instructionmap
pour appeler la fonction anonymex
.lambda x:x**2
dans la compréhension de liste est un bon substitut à
for
.map
Quand vous penserez à
, vous penserez à
Par exemple, je souhaite que seuls les nombres impairs apparaissent dansmap
, qui effectue des actions de filtrage sur les objets itérables.filter
:
lst2
visitera également son deuxième paramètre (un objet itérable), le retirera comme arguments dans l'ordre et appellera son premier paramètre (une fonction à paramètre unique si le résultat de l'opération est vrai ( ), la valeur de retour sera conservée en tant que nouvel élément, sinon (
a également un remplacement, qui est la compréhension de liste. Nous pouvons écrire comme ceci :filter
) sera filtrée.True
False
Et maintenantest également beaucoup plus simple ! On peut dire que l'instruction
if
en compréhension de liste est un bon substitut àfilter
.Après avoir vu ça, je crois que vous avez déjà compris :
Ce code exécute d'abord une compréhension de liste contenant l'instruction
for...in...
et l'instructionif
pour générer une liste, puis utilise la liste comme argument pour appeler la fonctionsum
.Conclusion :
for...in...
etif
ne sont pas directement liés àsum
.for...in...
etif
sont la syntaxe clé de la compréhension des listes.La compréhension de liste peut nous aider à générer des listes à l'aide d'objets itérables.
la compréhension de liste est un bon remplacement pour
map
etfilter
.