Ответ 1
x.append(y)
не эквивалентен x+[y]
; append
изменяет список на месте и ничего не возвращает, а x+[y]
- это выражение, которое возвращает результат.
Когда я выполняю этот код в python 2.6
reduce(lambda x,y: x+[y], [1,2,3],[])
Я получаю [1, 2, 3], как и ожидалось. Но когда я выполняю этот (я думаю, что это эквивалентно предыдущему)
reduce(lambda x,y: x.append(y), [1,2,3],[])
Я получаю сообщение об ошибке
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'append'
Почему эти две строки кода не дают одинакового результата?
x.append(y)
не эквивалентен x+[y]
; append
изменяет список на месте и ничего не возвращает, а x+[y]
- это выражение, которое возвращает результат.
reduce
вызывает функцию и использует возвращаемое значение в качестве нового результата. append
возвращает None
, и поэтому следующий вызов append
завершается с ошибкой. Вы можете написать
def tmpf(x,y):
x.append(y)
return x
reduce(tmpf, [1,2,3], [])
и получите правильный результат. Однако, если результатом является список того же размера, что и вход, вы не ищете сокращения: результат сокращения обычно должен быть единственным значением. Вместо этого используйте map или просто
[x for x in [1,2,3]]
Ожидается, что аргумент функции reduce
вернет результат операции.
x+[y]
делает это, тогда как x.append(y)
не делает (последний изменяет x
и возвращает None
).
Только для объяснения сообщения об ошибке:
AttributeError: 'NoneType' object has no attribute 'append'
Выражение
reduce(lambda x,y: x.append(y), [1,2,3],[])
эквивалентно
[].append(1).append(2).append(3)
Так как [].append(1)
не возвращает значение, то есть возвращает None
, он пытается выполнить (на втором шаге)
None.append(2)
в результате чего появляется сообщение об ошибке Nonetype object has no attribute append