2014-10-24 4 views
2

이 한 번 봐, 문제의 핵심은 맨 아래에 있습니다 : 즉StopIteration을 여기에서 제기하지 않는 이유는 무엇입니까?

>>> scan = iter('FHUR203459') 
>>> while True: 
     print(next(scan)) 


F 
H 
U 
R 
2 
0 
3 
4 
5 
9 
Traceback (most recent call last): 
    File "<pyshell#11>", line 2, in <module> 
    print(next(scan)) 
StopIteration 
>>> scan = iter('FHUR203459') 
>>> for i in range(12): # 12 * 2 for each join is 24, much longer than the string; should raise error. 
     print(''.join(next(scan) for i in range(2))) 


FH 
UR 
20 
34 
59 







>>> 

, 우리는하지만 그것은 단지에서 StopIteration 제기, 반복자는 두 경우 모두에서이 다한 것을 알 수 있습니다 첫 번째로, 비록 next()이 두 상황에서 모두 사용되었지만 마지막에 도달했습니다. 왜 join에서 사용하면 오류를 피하는 것 같습니다. 아니면이 버그입니까?

답변

2

StopIteration 어디서나 처리되지 않습니다. 그러나 두 번째 경우에,

''.join(next(scan) for i in range(2)) 

우리는 next(scan)에 의해 제기 StopIteration을 처리하고 모든 시간을 종료 발전기 표현식 ''.join-, 전달합니다. 그래서 ''.join은 빈 문자열을 생성합니다.

당신은 약간 같은 수정 및 ''.join에 목록을 전달하고 예외가 그것은 StopIteration이 실제로 발생 보여줍니다이

>>> scan = iter('FHUR203459') 
>>> for i in range(12): 
...  print(''.join([next(scan) for i in range(2)])) 
... 
FH 
UR 
20 
34 
59 
Traceback (most recent call last): 
    File "<input>", line 2, in <module> 
    File "<input>", line 2, in <listcomp> 
StopIteration 

처럼, 자신을 상승되는 것을 볼 수 있으며, 목록 이해 소요 히트, 이번.

+0

고맙습니다. 매우 유익했습니다. –

2

str.join()은 발전기에서 list()을 호출하며 해당 호출은 StopIteration을 삼켜합니다.

반복자 해야 캐치 StopIteration를 소비

아무것도; 예외를 제기 한 것은 정확히 중요하지 않습니다. 발전기 식으로을 사용 발전기의 발현 또는 아무것도 : 첫 번째 경우

>>> def raises_stopiteration(): raise StopIteration 
... 
>>> next(raises_stopiteration() for _ in range(10)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <genexpr> 
    File "<stdin>", line 1, in raises_stopiteration 
StopIteration 
>>> list(raises_stopiteration() for _ in range(10)) 
[] 
+0

정말요? 'str.join'은 '~을 listifies?! 그렇다면 발전기를 사용하는 이유는 무엇입니까? 'str.join'에서 list comprehension에 비해 generator를 사용하면 어떤 이점이 있습니까? – inspectorG4dget

+1

@ inspectorG4dget : 예, 문자열을 복사하기 전에 출력 크기를 미리 계산해야하기 때문에 목록에 표시됩니다. 결과에'str.join()'을 사용할 때 생성기 표현식 대신 목록 이해력을 사용하는 것이 더 빠릅니다 *. –

+0

@ inspectorG4dget'str.join'은 사전에 문자열의 길이를 알아야합니다. 따라서 목록을 전달하면 달리 반복해야합니다. 목록으로 변환하고 조인 한 문자열의 크기를 찾기 위해 다른 패스를 수행합니다. – thefourtheye

관련 문제