2016-09-29 1 views
1

Следующие два метода делают то же самое. Какой из них более эффективен с точки зрения сложности времени/пространства?Понимание списка 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: потребляет больше памяти, потому что он создает промежуточный список. Вместо этого используйте выражение генератора: 'для оценки в классе (класс ...): 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 выглядит странным и избыточным. Вы могли бы укоротить его до:

[some_operation(grade) for student in group.students for grade in student.grades] 

Но метод А лучше в любом случае, потому что он не создает список. Создание списка просто для того, чтобы выбросить его, сбивает с толку читателя и уничтожает память.

+0

Согласен. Просто не нравится несколько уровней циклов из-за моего OCD. Любая идея как написать сжатый, но не менее эффективный код в этом случае? – cheng

+0

Мне это очень не нравится. list-comprehensions являются выражениями и должны * not * использоваться только для функции calla в последовательности значений. Кроме того: он потребляет память. Если у вас есть сценарий, в котором у вас есть миллионы элементов для выполнения действия, вы, вероятно, не хотите создавать бесполезный список с миллионом элементов. – Bakuriu

+0

Нет, не сокращайте метод B до единого понимания списка. Метод B не создает новый список; понимание списка создает тот, который вы сразу же отбрасываете. – chepner

0

Они имеют ту же временную сложность, O(nm), так как это цикл по другой петле. Таким образом, n - group.students, а m - students.grades. Функционально, они должны быть одинаковой временной сложностью, так как она итерации по обоим спискам в любом случае.

Смежные вопросы