我在学习协同过滤,遇到这样一段代码
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]])
sum で受け入れられる最初のパラメータは反復可能です。この for ループの意味を知りたい場合は、ジェネレーターとそのジェネレーターに関連する構文シュガーを確認する必要があります。ポスター
の簡単な例を次に示します。[i for i in range(5)] # 结果为[0,1,2,3,4]
ここでの
for
またはif
はsum
自体とは何の関係もありません。@大鶉が言ったように、sum
は反復可能なオブジェクトをパラメーターとして受け入れます。この例の反復可能なオブジェクトは単なるものです。リスト内包表記を使用して生成された list。リスト内包表記 (逐次生産) を簡単に紹介しましょう。
関数型プログラミング の風味を備えた、直感的でエレガントな構文です。
その名前が示すように、シリーズを生成するために使用されます。
したがって、重要な原則があります:使用法を見てみましょう。リストを生成するには、文字通り 2 組の角括弧
(リストのリテラル生成構文) を使用して、
例を見てみましょう。今日、整数のリスト[]
反復を挟みます。for...in...
を使用してアクセスした要素は、リスト内の各要素を順番に作成するために使用されます。for
があり、各要素が
ループを使用しましたが、lst
の要素の 2 乗である別のリストlst2
を作成するとします。 リーリーlst
これを行うために標準のリスト内包表記
はfor...in...
を使用すると、同じことをより簡潔かつエレガントに実行できます。 リーリー この例では、内の要素を順番に取り出し、二乗演算を実行して
として使用して、匿名関数for i in lst
の新しい要素になります。 これはlst
関数を彷彿とさせますが、lst2
マッピングmap
を使用して同様の効果を実現することもできます。 リーリー は、2 番目のパラメーター (反復可能なオブジェクト) の要素を順番に訪問し、その要素をパラメーターとして使用して最初のパラメーター (単一パラメーター関数) を呼び出します。つまり、順番に取り出します。 1、2、3、4 をパラメータを呼び出します。
の良い代替品であると言えます。map
x
しかし、リスト内包の方がより直観的であることがわかり、リスト内包のlambda x:x**2
ステートメントはfor
map
を思い浮かべるでしょう。
map
たとえば、filter
に奇数のみを表示したい場合:
) はフィルターで除外されます。lst2
も 2 番目のパラメーター (反復可能なオブジェクト) を参照し、それを引数として順番に取り出し、操作の結果が true の場合 ( ) の場合、戻り値は新しい要素として保持されます。それ以外の場合 (filter
そして今、True
にはリスト内包表記も含まれています。False
のように書くことができます。リーリーもはるかに単純です。リスト内包の
if
ステートメントはfilter
の良い代替品であると言えます。これを見た後、あなたはすでに理解していると思います:
リーリーこのコードは、まず
for...in...
ステートメントとif
ステートメントを含むリスト内包表記を実行してリストを生成し、次にそのリストを引数として使用してsum
関数を呼び出します。結論:
for...in...
とif
はsum
に直接関係しません。for...in...
とif
はリスト理解の重要な構文です。リスト内包表記は、反復可能なオブジェクトを使用してリストを生成するのに役立ちます。
リスト内包表記は、
map
とfilter
の代替として適しています。