2013-01-02 7 views
0

reduce(mul, a)을 통해 빈 목록을 전달할 때 None 대신 1을 반환하려고합니다. 내 코드 :empty mul을 사용하여 빈 목록에 None 대신 None을 반환합니다.

from operator import mul 
def product_list(a): 
    for b in a: 
     b = reduce(mul, a) 
     if b == None: 
      return 1 
     return b 

print product_list([]) 

빈 목록을 잡기 위해 if 문을 어디에 두어도 출력에는 None이 계속 표시됩니다. 나는 아직도 기초를 배우고있다. 그러나 이것은 나에게 의미가 없다. 심지어는 없음을 잡을 수없고 (감소 하는가 1을 반환하면 나는 그것이 않습니다, 또는 금지 내 코드에 명백한 잘못이 있다고 생각하는 방식을 행동하지)를 참조 단지

from operator import mul 
def product_list(a): 
    if a == None: 
     return 1 
    else: 
     for b in a: 
      b = reduce(mul, a) 
      if b == None or a == None: 
       return 1 
      return b 

print product_list([]) 

을 시도했습니다 1을 반환하고 None을 반환합니다.

답변

6

a이 빈 목록이면 함수는 아무 것도 반환하지 않고 기본 반환 값은 None입니다. 상단에있는 빈 목록

테스트 : 두 번째 기능 당신 만 if a == None에 대한 테스트하지만, 빈리스트 []에서

if not a: 
    return 1 

None에 결코 동일합니다. 관용적 방법 대신 is 개체 확인 시험을 사용 None을 테스트 할 수 있습니다 : 대신 not a에 대한 시험으로

if a is None: 

을, 당신은 a 빈 목록을 수있는 Being None 인 경우를 모두 잡을 수있어.

코드는 달리 의미가 없습니다. 하지만 돌아가서 첫 번째 반복의 기능을 종료 a 이상 당신 루프 : 그러나

for b in a: 
    b = reduce(mul, a) 
    if b == None: 
     return 1 
    return b # exit the function here, having only looked at the first element in `a`. 

, 나는 게시물에 들여 쓰기를 수정했고, 그 return 문장의 들여 쓰기, 경우에 당신이 얻을 것이다를 오해 할 수있다 빈 목록을 전달할 때 NameError 대신

+0

빠른 답장을 보내 주셔서 감사합니다. 작동했는데, 어리 석다는 느낌이 들었습니다. 파이썬에 관한 튜토리얼을 계속 실행 중이므로, 왜 그렇게하는지 이해할 수 없습니다. 하지만 고마워. – FlyingNarwhal

0
if a is None or len(a) == 0: 
    return 1 

위와 같이 빈 목록 조건을 확인하십시오.

2

당신이 말하는 것처럼 당신은 빈 목록을 지나치지 않습니다. 사용해보기 :

>>> reduce(operator.mul, []) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: reduce() of empty sequence with no initial value 

아마도 reduce 기능을 이해하지 못한다고 생각합니다. 우리는 여러분을 반대 할 수는 없지만 파이썬 코드에서는 많이 사용되지 않습니다.

from operator import mul 
def product_list(a): 
    try: 
     return reduce(mul,a) 
    except TypeError: 
     return 1 

지금 당신이 그것을 시도 할 수 있습니다 :

print product_list([1,2,3,4]) #24 
print product_list([]) #1 
+0

"뛰어 넘기 전에 보길"(LBYL) 할 수 있음에 유의하십시오 :'a : return reduce (mul, a); EAFP보다 더 용서를 구하는 것이 더 쉽다. "(EAFP) – mgilson

+0

EAFP보다 LBYL이 더 좋다. 클라이언트가'Widget' 클래스를 정의하고 실수로 인스턴스를'product_list'로 전달한다고 가정하십시오. 우리는'product_list'가'TypeError'를 발생시키는 것을 선호 할 것입니다. 왜냐하면 위젯의 제품을 얻는 것이 타당하지 않기 때문입니다. 그러나 try-except 코드는 행복하게 1을 반환 할 것이고, 클라이언트는 코드가 작동한다고 생각하도록 속일 것이다. – Kevin

+0

@Kevin - 좋은 주장이지만, 어디서든 작성할 수있는 거의 모든 try-except 코드에 대해 사실상 동일한 주장을 할 수 있다고 생각합니다. EAFP의 이점은 발전기를이 함수에 전달할 수 있다는 것입니다. LBYL이라면 발전기를 찾을 필요가있을뿐만 아니라'bool (genertor)'는 항상'True'를주는 것처럼 보입니다. 요점은 코드 작성 방법에 관계없이 함수에 전달할 내용을주의 깊게 살펴야한다는 것입니다. 또는,'except'와'raise' 안에서'a'를 볼 수 있습니다. – mgilson

4

당신은 스타터 값으로 사용됩니다 reduce에 세 번째 값을 전달할 수 있습니다

아마도이 같은 함수를 정의하고 싶었다 .

In [6]: reduce(mul, [], 1) 
Out[6]: 1 

빈 목록을 처리하는 가장 좋은 방법입니다.케이스 None은 다른 종류의 오류이기 때문에 실제로 처리해야합니다. 프로그램의 의미에 아무런 문제가 없습니다. 누군가 다른 사람이 나쁜 데이터를 제공했기 때문입니다. 예를 들어, 당신이 그것을 반복 가능한하지 뭔가를 전달하면 물론

if not isinstance(..., collections.Iterable): 
    # do something 

, reduce에서 오류가 발생합니다, 그것은 당신을 위해 충분하다.

관련 문제