for..else
프로그램을 짜다 보면 for loop이 정상적으로 실행됐는지 중간에 break 됐는지 확인해야 할 상황이 생긴다. 보통은 is_broken
등의 플래그를 두는 식으로 짠다. 하지만 파이썬은 for..else라는 특이한 문법을 지원한다. 만약 for loop이 성공적으로 실행됐다면 else를 실행한다.
# w/o for..else
is_broken = False
for i in range(100):
if not testcase(i):
print(f'{i} failed')
is_broken = True
break
if not is_broken:
print('all passed!')
# w/ for..else
for i in range(100):
if not testcase(i):
print(f'{i} failed')
break
else:
print('all passed!')
만약 모든 testcase
가 성공한다면 all passed!
라고 뜰 것이고 만약 i
에서 실패한다면 failed
가 뜨게 될 것이다.
처음엔 살짝 혼란스러울 순 있어도 익숙해지면 오히려 가독성이 좋다.
바깥 for loop 생략하기 (Continuing to the next outer iteration within the inner loop)
# problem scenario
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
continue-ii-loop # 만약 여기 break을 넣게 되면 block1이 실행 된다. 그러지 않았으면 좋겠는 상황이다.
...block1...
우리가 원하는 건 jj
loop을 도는 동안 한번도 something
에 걸리지 않아야 block1
을 실행하는 것이다. 위는 pseudo-code이다. Inner loop 안에서 outer loop를 continue 시켜주기 위한 예약어는 없지만 for..else를 이용해 대충 구현이 가능하다.
# proposed solution
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
break
else:
...block1...
위와 같이 짜게 되면 something
에 걸리는 순간 break 되고 block1
이 실행되지 않는다.
출처
예시
나 같은 경우는 테스트 케이스를 위한 로그 파일들을 불러오면서 기록을 해놓고 파일들이 다 있는 경우에만 테스트 케이스를 실행하는 식으로 구현 할 때 사용헀다.
if args.test:
for p_case_dir in Path('test/logs').glob('**/*'):
for obj in ['node', 'job']:
p_obj = (p_case_dir / obj).with_suffix('.log')
if p_obj.is_file():
with p_obj.open() as f:
strings[f'{obj}_strings'] = f.read().strip().split('\n\n')
else:
break
else: # no break
print(p_case_dir.name)
SlurmTresVisualizer(**strings)
'파이썬 > 문법' 카테고리의 다른 글
Python | 클래스 변수와 클래스 메소드 (Class Variable, Class Method) (0) | 2018.06.27 |
---|