我在学习协同过滤,遇到这样一段代码
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]])
The first parameter accepted by sum is an iterable. If you want to know the meaning of this for loop, you need to check the generator and the syntactic sugar related to the generator. Here is a simple example for you
[i for i in range(5)] # 结果为[0,1,2,3,4]
The
for
orif
here have nothing to do withsum
itself. As @大quail said,sum
accepts an iterable object as a parameter. As for the iterable object in this example, it is a list generated using list comprehension.for
或是if
都跟sum
本身沒有什麼關係,如同 @大鹌鹑 所說,sum
接受一個可迭代的對象作為參數,至於這個例子中的可迭代對象就一個 使用 list comprehension 產生的 list。那就稍為介紹一下 list comprehension(串列產生式) 好了。
這是一個帶有 functional programming 味道的語法,直覺而優雅。
顧名思義,他是為了產生 串列 而被使用。
因此有一個重要的原則就是:
我們來看一下用法,非常簡單的,為了生成串列,所以我們字面上使用兩個成對的中括號
[]
( list 的字面產生語法),夾住一個for...in...
迭代式,利用for
走訪到的元素會被依序用來製造 list 中的各個元素。讓我們看例子,假設今天我們有一個整數的串列
lst
,我們想要製造另外一個串列lst2
,其中的每個元素都是lst
中元素的平方:我們使用了一個標準的
for...in...
迴圈來作到這件事,但同樣的事情,我們能夠用 list comprehension 作得更簡潔更優雅:在這個例子中,
for i in lst
會依序取出lst
中的元素進行平方運算後成為lst2
的新元素。 這讓人聯想到map
function,我們同樣可以使用 映射 來作到類似的效果:map
會依序走訪他第二個參數(一個可迭代對象)中的元素,並且將元素作為引數,調用他的第一個參數(一個單參數函數),也就是會依序取出 1, 2, 3 ,4 然後將之當成參數x
調用匿名函數lambda x:x**2
。但我們可以發現 list comprehension 更加直覺,我們可以說 list comprehension 中的
for
述句就是在map
的良好替代品。說到
map
就會想到filter
,他會對可迭代物件進行過濾的動作。比如說我想讓
lst2
裡面只出現奇數:filter
一樣會去走訪他的第二個參數(一個可迭代對象),並依序取出當成引數,調用他的第一個參數(一個單參數函數),若運算的結果為真(True
),則保留此回傳值作為新的元素,反之(False
)會被過濾掉。而現在
filter
Let’s briefly introduce list comprehension (serial production). #🎜🎜# #🎜🎜#This is a syntax with the flavor of functional programming, intuitive and elegant. #🎜🎜# #🎜🎜#As the name suggests, it is used to generate series. #🎜🎜# #🎜🎜#Therefore, there is an important principle: #🎜🎜#
#🎜🎜# Let’s take a look at the usage. It’s very simple. In order to generate a list, we literally use two pairs of square brackets
[]
(the literal generation syntax of list), clamp Afor...in...
iteration, the elements visited usingfor
will be used to create each element in the list in sequence. #🎜🎜# #🎜🎜#Let's look at an example. Suppose today we have a sequence of integerslst
, and we want to create another sequencelst2
in which each element is Is the square of the elements inlst
: #🎜🎜# #🎜🎜#We used a standardfor...in...
loop to do this, but for the same thing, we can use list comprehension Make it more concise and elegant: #🎜🎜# #🎜🎜#In this example,for i in lst
will sequentially take out the elements inlst
and perform a square operation to become the new element oflst2
element. This is reminiscent of themap
function. We can also use map to achieve similar effects: #🎜🎜# rrreee #🎜🎜#map
will sequentially visit the elements in its second parameter (an iterable object), and use the elements as arguments to call its first parameter (a single-parameter function) , that is, 1, 2, 3, and 4 will be taken out in sequence and then used as parametersx
to call the anonymous functionlambda x:x**2
. #🎜🎜# #🎜🎜#But we can find that list comprehension is more intuitive, and we can say that thefor
statement in list comprehension is a good substitute formap
. #🎜🎜##🎜🎜# Speaking of
map
,filter
will come to mind, which will perform filtering actions on iterable objects. #🎜🎜# #🎜🎜#For example, I want only odd numbers to appear inlst2
: #🎜🎜# rrreee #🎜🎜#filter
will also access its second parameter (an iterable object), take it out as arguments in sequence, and call its first parameter (a single-parameter function). If the result of the operation is true (True
), the returned value will be retained as a new element, otherwise (False
) will be filtered out. #🎜🎜# #🎜🎜#Nowfilter
also has a replacement, which is list comprehension. We can write like this: #🎜🎜#rrreeeIt’s also much simpler! We can say that the
if
statement in list comprehension is a good substitute forfilter
.if
述句就是filter
的良好替代品。看到這裡,相信你已經明白:
rrreee這段代碼,是先執行了一個含有
for...in...
述句和if
述句的 list comprehension 來產生 list 後,才以該 list 作為引數調用sum
函數。結論:
for...in...
和if
與sum
沒有直接關係。for...in...
和if
是 list comprehension 的關鍵語法。list comprehension 可以幫助我們使用可迭代對象產生 list。
list comprehension 是
map
和filter
After seeing this, I believe you already understand:
for...in...
statement and aif
statement to generate a list. Thesum
function is called with this list as an argument. #🎜🎜##🎜🎜#Conclusion: #🎜🎜#
for...in...
andif
are not directly related tosum
. #🎜🎜##🎜🎜#for...in...
andif
are the key syntax of list comprehension. #🎜🎜##🎜🎜#map
andfilter
. #🎜🎜##🎜🎜# #🎜🎜#