2014-12-26 4 views
2

Я нашел this учебник по использованию лямбда внутри python. При попытке сделать третий пример я обнаружил, что результаты не такие же, как в учебнике. Я на 99% уверен, что мой код верен, но здесь он тем не менее.Лямбда внутри функции фильтра?

my_list = [2,9,10,15,21,30,33,45] 

my_new_list = filter(lambda x: x % 3 == 0, my_list) 
print(my_new_list) 

Результатом этого является: <filter object at 0x004F39F0>

Вещи, чтобы иметь в виду:

  • Я использую Python 3.4.2
  • Использование Python 2.7.2 отлично работает и возвращается [9, 15, 21, 30, 33, 45]

Я понимаю, у него просто не работает в Python 3.4+; Мне более любопытно, почему это не работает, а также ищет равный способ сделать это с или без лямбда.

ответ

8

Разница в выходе вызвана тем фактом, что filter возвращает iterator в Python 3.x. Итак, вам нужно вручную вызвать list() на него, чтобы получить список:

>>> my_list = [2,9,10,15,21,30,33,45] 
>>> filter(lambda x: x % 3 == 0, my_list) 
<filter object at 0x01ACAB50> 
>>> list(filter(lambda x: x % 3 == 0, my_list)) 
[9, 15, 21, 30, 33, 45] 
>>> 

То же самое касается map, который также был изменен в Python 3.x, чтобы вернуть итератор. Вы можете прочитать об этих изменениях здесь: https://docs.python.org/3/whatsnew/3.0.html#views-and-iterators-instead-of-lists


Это говорит, filter и map, как правило, не любят программистов Python. Тем более, если вам нужно использовать lambda. Лучший подход в данном случае (и почти всех остальных) будет использовать list comprehension:

my_list = [2,9,10,15,21,30,33,45] 

my_new_list = [x for x in my_list if x % 3 == 0] 
print(my_new_list) 
+0

Отличный ответ! Спасибо, что объяснили это. Кроме того, спасибо, что показали мне предпочтительную альтернативу. –

4

Это потому, что в Python 3, фильтрующая функция возвращает итератор. Используйте list(my_new_list), чтобы получить все результаты. Чтобы быть ясным, дело не в том, что filter «не работает», но в Python 3.x это поведение отличается от 2.x.

См. How to use filter, map, and reduce in Python 3 для получения предыдущего ответа.

Причина в том, что если у вас есть большой список, обработка всех элементов сразу может быть нежелательной. Генератор будет выдавать результаты по требованию, позволяя вам сохранять память в том случае, если вы только закончите использовать часть результата (например, если итерация по фильтрованному списку).

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