🔥새해맞이 특별 라이브 선착순 신청🔥

(파이썬)for-else를 대체할 수 있을까?

# 행맨 게임 만들기 실습
# 제작 일자: 2021. 1. 28.
# 제작자: 김한울

# 1차 피드백: 2021. 2. 2.
# 몇 가지 이슈에 대해 수정하였다.
# 수정 1: 불필요한 인수, 디버깅의 흔적 등 읽기 어려운 부분을 조금 쳐냈다.
# 수정 2: 정답 체크 판정에 대해 주디님의 솔루션을 반영했다.

# 앞으로 할 일: 단어 리스트 내에서 문자열 무작위 추출.

print("Hello, what's your name?")
username = input(">>>>> ")
print()

while username == "":
    print("Please type your name!")
    username = input(">>>>> ")
    print()

print("Hello, {}! Let's play hangman game!".format(username))
print("The whole answer always use the lower cases.")
print()

answer = "apple" # 앞으로 할 일.
chance = 1
chanceLimit = 10 # 10번 안에 맞추지 않으면 게임오버.
answerHint = [] # 힌트 표시, 정답 판정을 위한 리스트.

for var in range(len(answer)): # 힌트 표시용 밑줄 생성.
    answerHint.append("_")

while chance <= chanceLimit:
    print("Hint: ", end="") # 힌트 표시.
    for var in range(0, len(answerHint)):
        print(answerHint[var], end=" ")

    print()
    print()

    userInput = input("{:02d}/{} try: ".format(chance, chanceLimit))
    print()

    if len(userInput) != 1 or userInput.isalpha() == False: # 알파벳 한 글자 입력 체크.
        print("Please type the single alphabet!")
        print()
    elif userInput in list(answer) and "".join(answerHint) != answer: # 알파벳을 하나 찾은 경우 판정.
        for idx, val in enumerate(answer): # 수정 2.
            if val == userInput and answerHint[idx] != userInput:
                answerHint[idx] = userInput
                print("You got one!")
                break
        else:
            print("You've already found that!")
        print()
        chance += 1
    elif userInput not in list(answer): # 틀렸을 경우 판정.
        print("Not in the answer!")
        print()
        chance += 1

    print()

    if "".join(answerHint) == answer: # 모든 정답을 찾은 경우 반복문 해제.
        break

if "".join(answerHint) == answer: # 승리.
    print("You won, {}! The answer is {}.".format(username, answer))
    print()
    exitBlocker = input("Press enter to exit.")
else: # 패배.
    print("You lost, {}. GAME OVER!".format(username))
    print()
    exitBlocker = input("Press enter to exit.")

 

 

 위 코드는 기존에 작성한 행맨 게임 코드(링크)여러 가지 피드백(링크)을 받아 일부를 수정한 것이다. 어려웠던 부분은 알파벳을 하나 입력받아 정답인 "apple"에 들어있는지 아닌지를 확인한 후, 그 결과를 answerHint 리스트에 반영하는 부분이었다. 주디님의 솔루션인 아래 코드는 그대로 사용해도 문제가 없었겠으나,

        for idx, val in enumerate(answer): # 수정 2 반영 전.
            if val == userInput:
                answerHint[idx] = userInput

 

 

 공부하자는 의미에서 일부러 한 글자씩 체크하는 코드로 변형해보았다.

        for idx, val in enumerate(answer): # 수정 2.
            if val == userInput and answerHint[idx] != userInput:
                answerHint[idx] = userInput
                print("You got one!")
                break
        else:
            print("You've already found that!")

 

 

 위 코드에서 특이한 부분이라면 역시 for-else 구문이다. for-else 구문을 처음 배웠을 땐 이런 걸 어디다 쓰지 하고 생각했었는데, 이걸 여기에 쓰고 있네.

 for-else 구문은 for의 조건(collections)이 False일 경우 else를 실행해주는 구조이다. 다시 말해서 끝까지 반복해도 break가 되지 않을 때 else로 넘어간다. 아래 순서도를 보면 이해하기 쉽다.(출처: https://blog.finxter.com/for-else-and-while-else-in-python-a-helpful-guide/)

for-else flowchart, https://blog.finxter.com/

 

 

 코드를 짜고 나서, for-else 구문이 거의 파이썬에서만 볼 수 있는 특이한 문법이라는 강의 내용이 떠올랐다. 다른 프로그래밍 언어에서는 for-else 구문을 이용하지 않고 동일한 작업을 할 수 있다는 이야기이다. 

 그렇다면 위의 코드 역시 for-else를 다른 방법으로 대체할 수 있을까? 다시 한 번 코드를 살펴보자.

        for idx, val in enumerate(answer): # 수정 2.
            if val == userInput and answerHint[idx] != userInput:
                answerHint[idx] = userInput
                print("You got one!")
                break
        else:
            print("You've already found that!")

 

 

 여기서 else를 사용하지 않겠다는 말은, else 대신 for의 마지막 시행에서 False가 되는 상황을 따져줘야 한다는 것이다.

        for idx, val in enumerate(answer): # 수정 2, else 미사용.
            if val == userInput and answerHint[idx] != userInput:
                answerHint[idx] = userInput
                print("You got one!")
                break
            elif not ( val == userInput and answerHint[idx] != userInput ) and idx == len(answer)-1:
                print("You've already found that!")

 

 

 True, False라는 관점에서 해독하지 못할 정도는 아니지만 그렇다고 읽기 쉬운 것도 아니다. 유지보수를 위해 그냥 else를 쓰는 편이 더 간단해보인다.

댓글을 작성해보세요.

채널톡 아이콘