파이썬 루프의 'else' 절을 어떻게 이해할 수 있습니까?
많은 파이썬 프로그래머들은 아마도 다음의 구문을 모를 것입니다.while
및 프루및for
에는 선택 인 " 에는옵포다니됩"가 포함되어 .else:
절:
for val in iterable:
do_something(val)
else:
clean_up()
else
절은 특정 종류의 정리 작업을 위한 좋은 장소이며, 루프의 정상적인 종료 시 실행됩니다. 즉, 다음을 사용하여 루프를 종료합니다.return
또는break
을뛰다너를 else
절 뒤에 ; 에뒤종료continue
실행합니다.나는 이것을 단지 내가 (다시) 찾아봤기 때문에 알고 있다, 왜냐하면 나는 언제인지 결코 기억할 수 없기 때문입니다.else
절이 실행됩니다.
항상요? 이름에서 알 수 있듯이 루프가 "실패"할 때?정기적으로 종료할 때?로 루프를 종료하더라도return
저는 그것을 찾아보지 않고서는 절대로 완전히 확신할 수 없습니다.
저는 키워드 선택에 대한 저의 지속적인 불확실성을 탓합니다.찾았습니다else
이 의미론에 대해 믿을 수 없을 정도로 비모닉적입니다.제 질문은 "왜 이 키워드가 이 목적에 사용되는가"가 아니라(답과 의견을 읽은 후에만 종료하도록 투표할 것입니다) 키워드에 대해 어떻게 생각해야 의미가 이해되고 따라서 기억할 수 있을까요?
이 부분에 대해서 상당히 많은 논의가 있었을 것이고 그리고 저는 이 부분에 대해서 일관성을 위해서 선택을 했다고 볼 수 있습니다.try
명서의세.else:
Python의 예약된 단어 목록에 추가하지 않기 위한 목적으로 절(저도 찾아봐야 합니다). 아도선택이유는을 일 것입니다.else
기능을 명확하게 하고 기억에 더 남을 수 있도록 하겠지만, 저는 역사적인 설명 자체가 아니라 이름과 기능을 연결하는 것을 추구합니다.
제 질문이 복제로 잠시 종결된 이 질문에 대한 답은 흥미로운 뒷이야기를 많이 담고 있습니다.제 질문은 다른 초점(특정 의미론을 연결하는 방법)을 가지고 있습니다.else
키워드 선택으로), 하지만 저는 이 질문에 대한 연결이 어딘가에 있어야 한다고 생각합니다.
안 안if
은 문이실니다됩을 합니다.else
조건이 false로 평가되는 경우 절. 동하게일▁a, a.while
loop은 조건이 false로 평가되면 else 절을 실행합니다.
이 규칙은 설명한 동작과 일치합니다.
- 일반 실행에서 while 루프는 조건이 false로 평가될 때까지 반복적으로 실행되므로 루프를 종료하면 자연스럽게 else 절이 실행됩니다.
- 를 할 때
break
문을 사용하면 조건을 평가하지 않고 루프를 종료하므로 조건이 false로 평가되지 않으며 other 절을 실행하지 않습니다. - 를 할 때
continue
문을 사용하면 조건을 다시 평가하고 반복을 시작할 때 일반적으로 수행했던 작업을 정확히 수행할 수 있습니다.따라서 조건이 참이면 계속 반복하지만 거짓이면 other 절을 실행합니다. - 다음과 같은 루프를 나가는 다른 방법
return
조건을 평가하지 않으므로 other 절을 실행하지 않습니다.
for
루프는 동일한 방식으로 작동합니다.반복기에 더 많은 요소가 있으면 조건을 참으로 간주하고 그렇지 않으면 거짓으로 간주합니다.
이렇게 생각하는 것이 좋습니다. 그else
앞에서 모든 것이 올바르게 진행되면 항상 차단이 실행됩니다.for
소모에 도달하도록 차단합니다.
바로 이 맥락에서 볼 때는 안 된다는 것을 의미합니다.exception
,아니요.break
,아니요.return
통제권을 빼앗는 모든 진술은for
원인이 될 것입니다.else
우회할 블록입니다.
반적인사사다례항검때목발음다니됩견색할에서 을 할 때 인 사용 됩니다.iterable
항목이 발견될 때 검색이 취소되거나 또는"not found"
래그는인통게양해쇄/다니됩다플을을 상승됩니다.else
슬라이드:
for items in basket:
if isinstance(item, Egg):
break
else:
print("No eggs in basket")
A continue
는 서에컨을않가습다에서 않습니다.for
그래서 통제는 다음으로 진행될 것입니다.else
에 for
지쳤습니다.
는 입니까?if
을 집행합니다else
조건이 거짓일 때.그것은 정확히 같은 것입니다.while
/else
그래서 당신은 생각할 수 있습니다.while
/else
한 냥그로서if
거짓으로 평가될 때까지 실제 조건을 계속 실행합니다.break
그것을 바꾸지 않습니다.평가 없이 포함 루프에서 점프합니다. 그else
평가하는 경우에만 실행됩니다.if
/while
조건이 false입니다.
그for
유사하지만 잘못된 조건은 반복기를 소모하는 것입니다.
continue
그리고.break
else
그것은 그들의 기능이 아닙니다. 그break
포함 루프를 종료합니다. 그continue
루프 조건이 평가되는 포함 루프의 맨 위로 돌아갑니다.그것은 평가하는 행위입니다.if
/while
또는 거또로으짓는또(()로으))for
more items를 실행하는 항목입니다.else
그리고 다른 방법이 없습니다.
이것이 본질적으로 의미하는 바입니다.
for/while ...:
if ...:
break
if there was a break:
pass
else:
...
이것은 다음과 같은 일반적인 패턴을 쓰는 더 좋은 방법입니다.
found = False
for/while ...:
if ...:
found = True
break
if not found:
...
그else
절은 다음이 있는 경우 실행되지 않습니다.return
return
의도한 대로 함수를 종료합니다.할 수 는 당이생수있예유외는한일는각입니다.finally
그의 목적은 항상 실행되도록 하는 것입니다.
continue
이 문제와 특별한 관련이 없습니다. 전체를 수 반복을 , 그 것은 합니다.break
.
try/else
유사:
try:
...
except:
...
if there was an exception:
pass
else:
...
루프를 이와 유사한 구조(일부 유사 코드)로 생각하는 경우:
loop:
if condition then
... //execute body
goto loop
else
...
조금 더 말이 될 수도 있습니다. 프는본로단지으적입니다.if
이 될 false
그리고 이것이 중요한 점입니다.루프는 자신의 상태를 확인하고 상태를 확인합니다.false
따서실니다됩을 합니다.else
인 것처럼 (처럼일인반))if/else
그런 다음 루프가 완료됩니다.
주의하세요.else
조건이 확인될 때만 get이 실행됩니다.즉, 예를 들어 실행 중에 루프의 본문을 종료하면 다음과 같이 됩니다.return
는또.break
다시 에, 상가다확않때기문에지인되태시▁since,에,else
케이스가 실행되지 않습니다.
A continue
반면에 현재 실행을 중지한 다음 루프의 상태를 다시 확인하기 위해 다시 점프합니다. 이것이 이유입니다.else
이 시나리오에서 도달할 수 있습니다.
루프의 시간과 함께 내 차의 순간.else
조항은 제가 레이먼드 헤팅어의 이야기를 보고 있을 때였는데, 그는 어떻게 그것이 불려져야 한다고 생각했는지에 대한 이야기를 했습니다.nobreak
다음 코드를 보십시오. 어떤 기능을 할 것 같습니까?
for i in range(10):
if test(i):
break
# ... work with i
nobreak:
print('Loop completed')
그것이 무엇을 한다고 생각하십니까? 음, 그은부라고 .nobreak
다음과 같은 경우에만 실행됩니다.break
진술서가 루프에 맞지 않았습니다.
보통 저는 다음과 같은 루프 구조를 생각하는 경향이 있습니다.
for item in my_sequence:
if logic(item):
do_something(item)
break
의 수변숫매비것우는슷지해와자와 .if/elif
문:
if logic(my_seq[0]):
do_something(my_seq[0])
elif logic(my_seq[1]):
do_something(my_seq[1])
elif logic(my_seq[2]):
do_something(my_seq[2])
....
elif logic(my_seq[-1]):
do_something(my_seq[-1])
이 경우에는else
for 루프의 문은 정확히 작동합니다.else
의 연쇄에 의한 진술.elif
True로 ( s, True로 을 중단합니다.return
가 이 않으면 것을 합니다.for: else
당신이 이 질문을 올린 정확한 이유: 그것은 비전문가입니다.
들▁▁mechanics다니▁the▁others습의 역학을 설명했습니다.while/for...else
그리고 Python 3 언어 참조는 권위적인 정의를 가지고 있습니다(잠시 후 참조). 하지만 여기 제 개인적인 기억법인 FWIW가 있습니다.저의 핵심은 이것을 두 부분으로 나누는 것이었습니다: 하나는 의미를 이해하기 위한 것입니다.else
루프 조건부와 관련하여, 루프 제어를 이해하기 위한 하나.
이해하는 것으로 시작하는 것이 가장 쉽다고 생각합니다.while...else
:
while
더 많은 아이템을 가지고 있고, 무언가를 하고,else
.
그for...else
니모닉은 기본적으로 동일합니다.
for
무언가를 , 모든항목, 무가를하지만언,하만가를지▁every.else
.
모두, 두경우모두,,else
부품은 처리할 항목이 더 이상 없고 마지막 항목이 정기적으로 처리된 경우에만 도달합니다(예: 아니오).break
또는return
) A.continue
그냥 돌아가서 물건이 더 있는지 확인해 보세요.이 규칙에 대한 내 기억법은 두 가지 모두에 적용됩니다.while
그리고.for
:
언제
break
ing 또는return
ing, 아무것도 없습니다.else
하기 위해서,
그리고 내가 말할 때continue
그것이 당신을 위한 "시작을 위한 루프백"입니다.
"시작하기 위해 루프백"을 의미하는 것은 분명하며, 반복 가능한 항목이 더 있는지 확인하는 루프의 시작입니다.else
걱정되는 것은continue
정말 아무 역할도 하지 않습니다.
TDD(Test-driven development)에서는 변환 우선 순위 전제 패러다임을 사용할 때 루프를 조건문의 일반화로 처리합니다.
이 접근법은 단순하다고 생각한다면 이 구문과 잘 결합됩니다.if/else
(아니오elif
) 문:
if cond:
# 1
else:
# 2
일반화:
while cond: # <-- generalization
# 1
else:
# 2
곱게
다른 언어로, 단일 사례에서 컬렉션이 있는 사례까지 TDD 단계는 더 많은 리팩터링을 필요로 합니다.
다음은 8thlight 블로그의 예입니다.
8thlight 블로그의 링크된 기사에서 Word Wrapkata는 문자열에 줄 바꿈을 추가하는 것으로 간주됩니다.s
아래 스니펫의 변수)는 주어진 폭에 맞도록 합니다.length
아래 스니펫에 변수가 있습니다.한 시점에서 구현은 다음과 같습니다(Java).
String result = "";
if (s.length() > length) {
result = s.substring(0, length) + "\n" + s.substring(length);
} else {
result = s;
}
return result;
현재 실패한 다음 테스트는 다음과 같습니다.
@Test
public void WordLongerThanTwiceLengthShouldBreakTwice() throws Exception {
assertThat(wrap("verylongword", 4), is("very\nlong\nword"));
}
따라서 조건부로 작동하는 코드가 있습니다. 특정 조건이 충족되면 줄 바꿈이 추가됩니다.우리는 여러 줄 바꿈을 처리할 수 있도록 코드를 개선하고 싶습니다.기사에 제시된 솔루션은 (if->while) 변환을 적용할 것을 제안하지만, 저자는 다음과 같은 논평을 내립니다.
루프가 가질 수 없는 반면
else
조항들, 그래서 우리는 제거할 필요가 있습니다.else
더 적은 작업을 수행함으로써 얻는 길if
경로입니다. 다시 말하지만, 이것은 리팩터링입니다.
이는 하나의 실패한 테스트의 맥락에서 코드를 더 많이 변경하도록 강제합니다.
String result = "";
while (s.length() > length) {
result += s.substring(0, length) + "\n";
s = s.substring(length);
}
result += s;
TDD에서 우리는 테스트를 통과할 수 있도록 가능한 한 적은 코드를 작성하기를 원합니다.Python의 구문 덕분에 다음과 같은 변환이 가능합니다.
출처:
result = ""
if len(s) > length:
result = s[0:length] + "\n"
s = s[length:]
else:
result += s
대상:
result = ""
while len(s) > length:
result += s[0:length] + "\n"
s = s[length:]
else:
result += s
내가 보기엔else:
반복해서 루프 끝을 지날 때 발생합니다.
네가 만약break
또는return
또는raise
당신은 루프의 끝을 지나 반복하지 않고, 즉시 멈추며, 따라서.else:
블록이 실행되지 않습니다.네가 만약continue
계속하려면 다음 반복으로 건너뛰기만 하면 되므로 루프의 끝을 지나 계속 반복합니다.그것은 루프를 멈추지 않습니다.
생각해 보세요.else
루프 구조의 일부로서의 절;break
루프 구조에서 완전히 벗어나므로 생략합니다.else
절
하지만 실제로 제가 생각하는 것은 단순히 C/C++ 패턴의 '구조화된' 버전이라는 것입니다.
for (...) {
...
if (test) { goto done; }
...
}
...
done:
...
그래서 내가 마주쳤을 때for...else
또는 직접 이해하기보다는 스스로 작성하여 위의 패턴 이해로 정신적으로 번역한 다음 파이썬 구문의 어떤 부분이 패턴의 어떤 부분에 매핑되는지 파악합니다.
(코드가 정형인지 비정형인지가 아니라 특정 구조에 전용 키워드와 문법이 있는지만 차이가 있기 때문에 '구조화'를 scarec 인용문에 넣었습니다.)
짝을 이룰 경우else
와 함께for
혼란스러울 수 있습니다.키워드가 아닌 것 같아요.else
이 구문에 대한 훌륭한 선택이었지만, 만약 당신이 짝을 이룬다면.else
와 함께if
을 포함하는 것.break
당신은 그것이 실제로 말이 되는 것을 볼 수 있습니다. else
선행이 없는 경우에는 거의 유용하지 않습니다.if
구문 설계자가 키워드를 선택한 이유가 여기에 있다고 생각합니다.
인간의 언어로 설명해 보겠습니다.
for
용의자 그룹의 각 사람들if
누구나 범죄자입니다.break
조사else
실패를 보고
제가 생각하기에, 핵심은 그 의미를 고려하는 것입니다.continue
보다는else
.
당신이 언급한 다른 키워드들은 (비정상적으로 퇴장하는) 동안 루프를 이탈합니다.continue
그렇지 않습니다. 루프 안에 있는 코드 블록의 나머지 부분만 건너뜁니다.루프 종료에 선행할 수 있다는 사실은 부수적입니다. 실제로 종료는 루프 조건식의 평가에 의해 정상적인 방법으로 수행됩니다.
그렇다면 당신은 단지 기억하기만 하면 됩니다.else
절은 일반 루프 종료 후에 실행됩니다.
다음과 같은 문구가 있습니다.else
절
while condition:
iteration
else:
conclusion
와 정확히 일치합니다.
while True:
if not condition:
conclusion
break
iteration
다음과 같은 문구가 있습니다.else
절
for item in iterable:
iteration
else:
conclusion
와 정확히 일치합니다.
iterator = iter(iterable)
while True:
try:
item = next(iterator)
except StopIteration:
conclusion
break
iteration
그것은 효과를 이해하는 데 도움이 됩니다.break
또는continue
반복 문에 있는 문입니다.
참고 - 의 경우while
그리고.for
가 없는 진술else
절, 결론 문장을 다음으로 대체합니다.pass
동등한 코드의 문.
# tested in Python 3.6.4
def buy_fruit(fruits):
'''I translate the 'else' below into 'if no break' from for loop '''
for fruit in fruits:
if 'rotten' in fruit:
print(f'do not want to buy {fruit}')
break
else: #if no break
print(f'ready to buy {fruits}')
if __name__ == '__main__':
a_bag_of_apples = ['golden delicious', 'honeycrisp', 'rotten mcintosh']
b_bag_of_apples = ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
buy_fruit(a_bag_of_apples)
buy_fruit(b_bag_of_apples)
'''
do not want to buy rotten mcintosh
ready to buy ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
'''
언급URL : https://stackoverflow.com/questions/37642573/how-can-i-make-sense-of-the-else-clause-of-python-loops
'programing' 카테고리의 다른 글
유형 스크립트의 정적 메서드에서 클래스 유형 인수에 액세스하기 위한 해결 방법 (0) | 2023.06.20 |
---|---|
클릭 후 VBA Excel 버튼 크기 조정(명령 버튼) (0) | 2023.06.20 |
pyspark 데이터 프레임에 고유한 열 값 표시 (0) | 2023.06.20 |
PL/SQL에서 문자열을 비교하는 방법은 무엇입니까? (0) | 2023.06.20 |
진술이란 무엇입니까?setFetchSize(nSize) 메서드가 SQL Server JDBC 드라이버에서 실제로 수행됩니까? (0) | 2023.06.20 |