2014-01-25 4 views
4
total = sum([float(item) for item in s.split(",")]) 


total = sum(float(item) for item in s.split(",")) 

Источник: https://stackoverflow.com/a/21212727/1825083Почему существует разница между двумя строками кода?

+0

Не знаю, стоит ли упомянуть ответ 'str.join' и несколько других функций, которые будут принимать итератор, но сразу же называть 'list()' на нем. Поэтому я просто упомянул об этом здесь, в комментарии. – abarnert

ответ

6

Первый использует list comprehension для построения списка всех значений поплавка.

Второй использует generator expression для создания генератора, который только строит каждое значение поплавка по запросу, одно время. Это экономит много памяти, когда список будет очень большим.

Выражение генератора также может быть либо более быстрым (поскольку оно позволяет конвейеру обрабатывать работу, а также избегать времени выделения памяти) или медленнее (поскольку оно добавляет немного накладных расходов), но это обычно не является веской причиной для выбора между ними , Просто следуйте этому простому эмпирическому правилу:

Если вам нужен список (или, скорее, только что-то, что вы можете хранить, перебирать несколько раз, распечатывать и т. Д.), Создать список. Если вам просто нужно перебрать значения, не создавайте список.

В этом случае, очевидно, вам не нужен список, поэтому оставьте квадратные скобки.


В Python 2.x есть некоторые другие незначительные отличия; в 3.x определение списка фактически определяется как просто вызов функции list в выражении генератора. (Хотя есть небольшая ошибка, по крайней мере, 3.0-3.3, которую вы найдете только в том случае, если ищете ее очень сложно ...)

+0

Любопытно об ошибке сейчас. : P –

+0

@SukritKalra: Я дам вам подсказку: попробуйте вызвать функции, которые «поднимают StopIteration» и «поднять GeneratorExit» из разных мест в понимании. – abarnert

+0

@SukritKalra: Если вы сдаетесь, см. [Этот пост в блоге] (http: //stupidpythonideas.blogspot.ком/2013/06/может вы-оптимизируют-listgenexp.html). Я не уверен на 100%, что пример, который я дал, имеет единственное различие; Я почти уверен, что исправление, предлагаемое в конце, устраняет не только эту разницу, но и любые другие неоткрытые различия. (Моя цель, кстати, заключалась в том, чтобы экспериментировать с оптимизатором подглядывания для кода, который делает последовательности непосредственно из genexprs, и я получил завышенную сторону.) – abarnert

1

Первый создает список, и суммирует числа в списке. Это понимание списка внутри суммы

Вторая вычисляет каждый элемент по очереди и добавляет его в текущее итоговое значение и возвращает текущее итоговое значение как сумму, когда все элементы исчерпаны. Это понимание генератора.
Он вообще не создает список, а это означает, что не требуется дополнительное время для распределения памяти для списка и заполнения его. Это также означает, что он имеет лучшую пространственную сложность, поскольку он использует только постоянное пространство (для вызова float, кроме звонка на split, который обе строки делают)

5

Первый делает список, а второй является выражением генератора. Попробуйте их без вызова функции sum().

In [25]: [float(a) for a in s.split(',')] 
Out[25]: [1.23, 2.4, 3.123] 

In [26]: (float(a) for a in s.split(',')) 
Out[26]: <generator object <genexpr> at 0x0698EF08> 

In [27]: m = (float(a) for a in s.split(',')) 

In [28]: next(m) 
Out[28]: 1.23 

In [29]: next(m) 
Out[29]: 2.4 

In [30]: next(m) 
Out[30]: 3.123 

Таким образом, первое выражение создает весь список в памяти, а затем вычисляет сумму, тогда как второй один раз получает следующий элемент в выражении и добавляет его в общей совокупности. (Больше памяти эффективно)

2

Как и другие, первый создает список, а второй создает генератор, который генерирует все значения. Причина, по которой вам может быть интересно, заключается в том, что создание списка сразу же помещает все элементы в память, тогда как с генератором вы можете обрабатывать их по мере их создания без необходимости их хранения, что может иметь значение для очень больших объемов данных ,

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