2017-12-11 9 views
2

내가 reduce를 사용하여 목록을 분할하는 하나의 방법 보여준 answer from this site에서 가져온 다음 코드에서 or 키워드의 사용을 이해할 수 없다 : 나는 코드가 첫 번째 목록에 추가됩니다 이해다음 코드에서 'or'키워드를 사용하는 것은 무엇입니까?

def partition(l, p): 
    return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], [])) 

을 조건이 true 인 경우는 두 번째 조건에 추가됩니다. 부품 or x은 무엇을합니까? 나는 그것을 나가려고 노력했다. 그러나 나는 말하기와 함께 끝났다. TypeError: 'NoneType' object is not subscriptable

+1

완전한 함수 정의에서 실제로 진술해야하는 더 복잡한 표현식을 작성하는 것은 더러운 해킹입니다. 어떤 사람들은'lambda' 함수로 영리 해지기를 좋아합니다. –

답변

5

누군가 골프는 코드 다. list.append()항상은 거짓 값인 None을 반환합니다. or을 사용하여 lambda은 두 번째 표현식의 결과를 반환 할 수 있습니다. None or ...항상...의 결과를 반환합니다.

당신은 전체 함수 정의와 lambda을 대체 할 수 :

def func(x, y): 
    x[not p(y)].append(y) 
    return x 

모두 lambda하고, 상기 재 정의는 누적 값을 각각의 호출에 reduce() 패스 인 x 인수를 반환합니다. 이 경우 분할 된 값이 수집되는 두 개의 목록이있는 튜플입니다. 결국,

def partition(l, p): 
    a, b = [], [] 
    for v in l: 
     target = a if not p(v) else b 
     target.append(v) 
    return a, b 

가독성 문제 :

개인적으로, 난 그냥 루프를 사용했을 것입니다. 이 부가 기능 호출 (입력 목록에서 값 당 하나의 추가 통화)를 피할 수 있기 때문에 또한, 그것은 꽤 빨리도 : 1000 회 10,000 항목 목록을 구획하는 그래서

>>> import timeit 
>>> import random 
>>> testdata = [random.randrange(1000) for _ in range(10 ** 4)] 
>>> predicate = lambda v: v % 2 == 0 
>>> def partition_lambda(l, p): 
...  return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], [])) 
... 
>>> def partition_readable(l, p): 
...  a, b = [], [] 
...  for v in l: 
...   target = a if not p(v) else b 
...   target.append(v) 
...  return a, b 
... 
>>> timeit.timeit('part(l, p)', 'from __main__ import partition_lambda as part, testdata as l, predicate as p', number=10**3) 
2.5286515180487186 
>>> timeit.timeit('part(l, p)', 'from __main__ import partition_readable as part, testdata as l, predicate as p', number=10**3) 
1.6824414430302568 

, 읽기 가능한 버전은 소요 reduce() 버전에 소요되는 시간의 2/3에만 해당됩니다.

관련 문제