2016-09-29 4 views
1

次の2つのメソッドは同じことをします。どれが時間/空間の複雑さの面でより効率的ですか?Pythonのリストの理解とネストされたループ、簡潔さ/効率

** Method A** 
for student in group.students: 
    for grade in student.grades: 
     some_operation(grade) 

** Method B** 
for grade in [grade for student in group.students for grade in student.grades] 
    some_operation(grade) 
+1

B:中間リストを作成するため、メモリを消費します。代わりにジェネレータ式を使用してください: 'grade in(grade ...):some_operation(grade)'。 – Bakuriu

+0

@Bakuriu、 "()"はジェネレータを示しますか?だから私たちはそれをループするので、 '成績'のリストは作成されませんか? – cheng

+0

関連スレッド http://stackoverflow.com/questions/47789/generator-expressions-vs-list-comprehension http://stackoverflow.com/questions/19933753/generator-vs-list-comprehension – cheng

答えて

1

方法Bは奇妙で冗長です。

しかし、方法Aはリストを作成しないためどちらかの方が優れています。単にそれを放棄するためのリストを作ることは、読者に混乱させ、メモリを浪費する。

+0

合意。 OCDのために、複数レベルのループが好きではありません。この場合、簡潔で効率的なコードを書く方法はありますか? – cheng

+0

私はこれを強く嫌っています。 list-comprehensionsは式であり、一連の値に対して関数を呼び出すだけでは使用できません。それ以外にも、それはメモリを消費します。あなたがアクションを実行する何百万ものアイテムを持っているシナリオがあるなら、おそらく何百万もの要素を持つ無駄なリストを作成したくないでしょう。 – Bakuriu

+0

いいえ、方法Bを単一のリストの理解に短縮しないでください。メソッドBは新しいリストを作成しません。リストの理解はあなたがすぐに捨てるものを作成します。 – chepner

0

これらは、別のループをループしているため、同じ時間の複雑さ、O(nm)です。したがって、ngroup.studentsであり、mstudents.gradesです。機能的には、これらはどちらの方法でも両方のリストを反復処理するので、同じ時間の複雑さでなければなりません。

関連する問題