2016-11-21 11 views
3
res = sum((i+j)%k == 0 for x, i in enumerate(a) for j in a[x+1:]) 

ここで、aは配列です。以下のようにコーディングするには、どうすれば "pythonic"を書くことができますか?

私はこのコードが何をしているのか理解できません。i in enumerate(a) for j in a[x+1:]はスペースを節約するために基本的にそのループ内のforループですか?

また、どうすればこのようなコードを書くことができますか?私はPythonを学ぼうとしています。

答えて

4

次のようにコードを「ほどく」ことができます。

counter=0 # emulates `sum` 
for x, i in enumerate(a): 
    for j in a[x+1:]: 
     counter += (i+j)%k == 0 

ので、それは同じ半分と同一の要素をカウントするために避け、(i+j)kで割り切れることの出現をカウント(上面のみ行列の三角形をカウント)

リスト/ジェネレータの補完は、繰り返し可能な繰り返し可能な繰り返し可能なリストからリストを作成したときに、より良い/より速く簡潔になります。たとえば、sumを数えるブール値のリスト(0または1)出現はTrueです。

しかし、それらの乱用しないでください:proper use of list comprehensions - python

時々関数を呼び出すのn倍にするプレーンなループが(副作用が必要な時も)優れています。

使用する場合愚か彼らが理解するために悪夢になることができますが(その中の副作用と特別ワンライナー)

+0

で割り切れますが、これは技術的にジェネレータの表現ではなく、リストの理解ではありませんか?だからあなたは本当にメモリに 'list'を作成することはありません。 – Keiwan

+0

はい、それは発電機の理解です。 'sum'はメモリ内のリストを持つ必要がないので、一時リストは作成されません。 –

+0

この場合、サム関数はカウンタを加算していますか? – jessibird

2

これらが内包表記と呼ばれています。 enumerateは反復可能オブジェクトを反復処理し、反復子の(a, b)タプルを返します。aはインデックスであり、bはそのインデックスのオブジェクトです。

これは素晴らしいコードです。このようなことを理解する/書く方法を学ぶ上で、Pythonのドキュメントを読むことは始めるのに最適な場所です。覚えておいてください、これは単に文法的な砂糖です。同じことを複数の行で行うことができ、ほぼ同じように動作します。

6

これは、sum関数の呼び出しの中のジェネレータ式です。 sumだけで物事を追加し、その者は、ジェネレータ式を見てみましょう:

(i+j)%k == 0 for x, i in enumerate(a) for j in a[x+1:] 

(i+j)%k == 0一部はブール式です。 i+jkで除算された場合、0の剰余を持つ場合はtrue、そうでない場合はfalseです。きちんとした小さなトリックとして、Trueの値は、Pythonで1の数値を持ち、Falseの数値は0です。だから、これは基本的に数えています。

for x, i in enumerate(a) for j in a[x+1:] 

これは基本的にネストされたforループです。

for x, i in enumerate(a): 
    for j in a[x+1:]: 

enumerate

は一緒にそう [a, b, c]がすべて [(0, a), (1, b), (2, c)]

スティックになり、それらのインデックスと対に反復可能でアイテムを生成関数であり、このコードは、そのようなリストの要素の対の数を計算しますそれらの合計はk

関連する問題