[python] Python 3에서 필터, 맵 및 축소를 사용하는 방법

filter, map그리고 reduce완벽하게 파이썬 2. 다음의 작업은 예입니다 :

>>> def f(x):
        return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

>>> def cube(x):
        return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

>>> def add(x,y):
        return x+y
>>> reduce(add, range(1, 11))
55

그러나 파이썬 3에서는 다음과 같은 결과가 나타납니다.

>>> filter(f, range(2, 25))
<filter object at 0x0000000002C14908>

>>> map(cube, range(1, 11))
<map object at 0x0000000002C82B70>

>>> reduce(add, range(1, 11))
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    reduce(add, range(1, 11))
NameError: name 'reduce' is not defined

누군가 이것이 왜 그런지 설명해 주시면 감사하겠습니다.

더 명확하게하기위한 코드 스크린 샷 :

파이썬 2와 3의 유휴 세션



답변

Python 3.0의 새로운 기능 변경 사항에 대해 읽을 수 있습니다 . 로트가 많이 변경되었으므로 2.x에서 3.x로 이동할 때 반드시 읽어야합니다.

여기에 전체 답변은 문서에서 인용 한 것입니다.

목록 대신보기 및 반복자

잘 알려진 일부 API는 더 이상 목록을 반환하지 않습니다.

  • […]
  • map()filter()반복자를 돌려줍니다. 실제로 목록이 필요한 경우 빠른 수정은 예를 들어 list(map(...))더 나은 수정은 종종 목록 이해 (특히 원본 코드가 람다를 사용하는 경우)를 사용하거나 코드를 다시 작성하여 목록이 전혀 필요하지 않은 것입니다. map()기능의 부작용에 대해 특히 까다로운 것이 발생합니다. 올바른 변환은 정기적 인 for루프 를 사용하는 것입니다 (목록을 작성하는 것은 낭비이기 때문에).
  • […]

내장

  • […]
  • 제거되었습니다 reduce(). functools.reduce()정말로 필요한 경우 사용하십시오 . 그러나 명시 적 for루프가 더 읽기 쉬운 시간의 99 %입니다 .
  • […]

답변

의 기능 map과는 filter의도적 반복자를 반환하도록 변경되었으며,되는 것을 제거 줄일 A의 내장에 위치 functools.reduce.

for filter및을 map사용 list()하여 이전과 같은 결과를 볼 수 있습니다 .

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> list(filter(f, range(2, 25)))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> list(map(cube, range(1, 11)))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> import functools
>>> def add(x,y): return x+y
...
>>> functools.reduce(add, range(1, 11))
55
>>>

권장 사항은 맵 및 필터 사용법을 생성기 표현식 또는 목록 이해로 대체하는 것입니다. 예:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> [i for i in range(2, 25) if f(i)]
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> [cube(i) for i in range(1, 11)]
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>>

그들은 for 루프가 줄어든 것보다 99 % 더 읽기 쉽다고 말합니다 functools.reduce.

편집 : 99 % 수치는 Guido van Rossum이 작성한 What ‘s New in Python 3.0 페이지 에서 직접 가져온 것 입니다.


답변

다른 답변에 대한 부록으로,이 함수의 이름을 목록을 반환 reduce하고 전역 네임 스페이스에 도입하는 함수에 다시 매핑하는 컨텍스트 관리자의 훌륭한 사용 사례처럼 들립니다 .

빠른 구현은 다음과 같습니다.

from contextlib import contextmanager

@contextmanager
def noiters(*funcs):
    if not funcs:
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func

다음과 같은 사용법으로 :

with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))

어떤 지문 :

190
[1, 2]

그냥 내 2 센트 🙂


답변

때문에 reduce방법은 Python3에서 기능 내장에서 제거 된의를 가져 잊지 마세요 functools코드에. 아래 코드 스 니펫을 참조하십시오.

import functools
my_list = [10,15,20,25,35]
sum_numbers = functools.reduce(lambda x ,y : x+y , my_list)
print(sum_numbers)


답변

다음은 필터, 맵 및 축소 기능의 예입니다.

숫자 = [10,11,12,22,34,43,54,34,67,87,88,98,99,87,44,66]

//필터

oddNumbers = list (필터 (람다 x : x % 2! = 0, 숫자))

print (oddNumbers)

//지도

multiplyOf2 = list (맵 (람다 x : x * 2, 숫자))

인쇄 (multiplyOf2)

//줄이다

reduce 함수는 일반적으로 사용되지 않기 때문에 Python 3의 내장 함수에서 제거되었습니다. functools 모듈에서 계속 사용할 수 있으므로 다음을 수행 할 수 있습니다.

functools에서 가져 오기 감소

sumOfNumbers = 축소 (lambda x, y : x + y, 숫자)

print (sumOfNumbers)


답변

지도, 필터링 및 축소의 장점 중 하나는 복잡한 것을 수행하기 위해 함께 “체인”할 때 이들이 가독성이 있다는 것입니다. 그러나 내장 구문은 읽을 수 없으며 모두 “뒤로”입니다. 따라서 PyFunctional패키지 ( https://pypi.org/project/PyFunctional/ )를 사용하는 것이 좋습니다 .
다음은 두 가지를 비교 한 것입니다.

flight_destinations_dict = {'NY': {'London', 'Rome'}, 'Berlin': {'NY'}}

PyFunctional 버전

매우 읽기 쉬운 구문. 당신은 말할 수 있습니다 :

“나는 일련의 비행 목적지를 가지고있다. 도시가 dict 값에 있으면 dict 키를 얻고 싶다. 마지막으로, 프로세스에서 생성 한 빈리스트를 걸러 내라.”

from functional import seq  # PyFunctional package to allow easier syntax

def find_return_flights_PYFUNCTIONAL_SYNTAX(city, flight_destinations_dict):
    return seq(flight_destinations_dict.items()) \
        .map(lambda x: x[0] if city in x[1] else []) \
        .filter(lambda x: x != []) \

기본 파이썬 버전

모두 거꾸로입니다. 당신은 말할 필요가있다 :

“좋아요,리스트가 있어요. 빈리스트를 걸러 내고 싶어요. 왜? 도시가 dict 값에 있으면 먼저 dict 키를 얻었 기 때문입니다. 아, 제가하고있는리스트는 flight_destinations_dict입니다. “

def find_return_flights_DEFAULT_SYNTAX(city, flight_destinations_dict):
    return list(
        filter(lambda x: x != [],
               map(lambda x: x[0] if city in x[1] else [], flight_destinations_dict.items())
               )
    )


답변