본문 바로가기
Programmers/programmers

[프로그래머스]로그인 성공? 파이썬 // 왈러스 연산자 , 변수초기화의 중요성.

by 딸기뚜왈기 2023. 12. 11.

실패코드

def solution(id_pw, db):
    for idpw in db:
        if idpw[0] == id_pw[0]:
            if idpw[1] == id_pw[1]:
                answer = "login"
            else:
                answer = "wrong pw"
        else:
            answer = "fail"
    return answer

체점결과, 1번 테스트케이스 실패.

 

반례>

입력값 〉 ["abc04", "345"], [["abc04", "335"], ["abc03", "345"]]
기댓값 〉 "wrong pw"

순서에 있어서 우선순위가 있는 것이 반례라고 한다.

 

 

성공코드(continue 사용해서 수정)

def solution(id_pw, db):
    for idpw in db:
        if idpw[0] == id_pw[0]:
            if idpw[1] == id_pw[1]:
                answer = "login"
            else:
                answer = "wrong pw"
        
        else:
            if idpw[1] == id_pw[1]:
                continue
            else: 
                answer = "fail"
    return answer

id는 다른데, pw가 다른 경우,

다음 반복을 돌 수 있도록 continue를 해줬다.

 

continue 문이 실행되면

현재 반복의 나머지 부분을 건너뛰고

루프의 다음 반복으로 이동한다.

 

continue 문이 실행되면  (for idpw in db:) 다음 반복을 진행한다.

 

단점 : 조건문의 구성을 보면 중첩된 if-else가 사용되어 코드가 복잡하다. (수정 필요)

 

 

 

다른 방법 1.(continue 없이)

def solution(id_pw, db):
    for id, pw in db:
        if id == id_pw[0] and pw == id_pw[1]:
            return "login"
        elif id == id_pw[0]:
            return "wrong pw"
    return "fail"
  1. db에 있는 각 사용자 정보(id와 pw)에 대해 반복.
  2. 현재 반복 중인 사용자의 아이디(id)와 비밀번호(pw)가 주어진 id_pw와 일치하는지 확인.
  3. 일치하면 "login"을 반환하고 함수 종료. (아이디와 비밀번호가 모두 일치하는 사용자를 찾았을 때의 상황)
  4. 일치하지 않고, 아이디만 일치하는 경우 "wrong pw"를 반환하고 함수 종료. (아이디는 일치하지만 비밀번호가 일치하지 않는 사용자)
  5. 만약 루프를 모두 돌아도 위 두 경우에 해당하지 않으면 "fail"을 반환. (주어진 아이디에 해당하는 사용자가 없는 경우)

 

다른 방법 2. (answer을 초기화한 방법)

def solution(id_pw, db):
    answer = 'fail'
    for id, pw in db:
        if id_pw[0] == id:
            if id_pw[1] == pw:
                answer = 'login'
            else:
                answer = 'wrong pw'
    return answer

 

 

<위 두 코드의 차이점>

 

변수 초기화(다른 방법 2) :

answer를 미리 'fail'로 초기화하고,

조건을 만족하는 경우에만 값을 갱신하도록 한다.

 

다른 방법 1에서는 answer를 초기화하지 않음.

이 경우, 만약 db가 비어있으면 answer가 정의되지 않은 상태로 남을 수 있다.

만약 db가 비어있는 경우, for idpw in db 루프가 실행되지 않으므로 answer가 아무런 값도 갖지 않은 채로 함수가 종료된다.

그럼 answer 변수는 존재하지 않게 된다.

다른방법 2 코드에서는 answer를 미리 'fail'로 초기화하여 이러한 문제를 방지했다.

 

루프 동작 효율성(다른 방법 1): 

다른 방법 2 코드에서는 for 루프를 모두 돌고 난 후에야 최종적인 answer 값을 반환한다.

다른방법 1 코드에서는 루프를 도는 중에 이미 return 문을 통해 결과를 반환할 수 있다.

따라서 다른방법 1 코드는 한 번의 루프에서 조건에 맞는 결과를 찾으면 루프를 종료할 수 있다.

 

 

 

 

위 두(다른방법1, 2) 코드의 혼합.

def solution(id_pw, db):
    answer = "fail"
    for id, pw in db:
        if id == id_pw[0]: 
            if pw == id_pw[1]:
                return "login"
            else:
                return "wrong pw"
    return answer

 

변수초기화 :

변수 초기화 해서 db가 비어있을 경우에도 for문을 돌 수 있도록 해주었다.

루프 동작 : for문을 전부 다 돌 필요없이 return을 할 수 있게 해주었다.

 

 

 

 

왈러스 연산자 사용 코드(처음 본다.)

def solution(id_pw, db):
    if db_pw := dict(db).get(id_pw[0]):
        return "login" if db_pw == id_pw[1] else "wrong pw"
    return "fail"

 

:=왈러스 연산자로, 변수에 값을 할당하고 동시에 그 값을 반환한다.

이를 통해 db_pw에는 get 메서드를 통해 가져온 데이터베이스의 비밀번호가 할당된다.

 

왈러스 연산자(:=)와 get 메서드를 사용하여 주어진 id_pwdb에 존재하는지 확인한다.

만약 존재한다면, 해당 ID에 연결된 비밀번호가 제공된 비밀번호와 일치하는지 확인한다.

 

dict(db)는 이를 딕셔너리로 변환한다.

그리고 get(id_pw[0])는 딕셔너리에서 id_pw[0]라는 키에 해당하는 값을 가져온다.

만약 해당 키가 딕셔너리에 없으면 None을 반환한다.

 

 

예를 들어,

db에 들어간 데이터구조가 [id:1234, pw:4321] ,[id:6789, pw:9876 ]이라고 치고, 입력된 id와 pw가 1234, 9876 이라고 했을때,

def solution(id_pw, db):
    if db_pw := dict(db).get(id_pw[0]):
        return "login" if db_pw == id_pw[1] else "wrong pw"
    return "fail"

db = [
    {'id': 1234, 'pw': 4321},
    {'id': 6789, 'pw': 9876}
]


result = solution([1234, 9876], db)
print(result)



  1. id_pw[0]는 1234이고, db에서 이에 해당하는 딕셔너리를 찾는다.
  2. dict(db).get(1234)는 db 리스트를 딕셔너리로 변환한 뒤에 1234 키에 대한 값을 가져온다. 여기서 가져오는 값은 {'id': 1234, 'pw': 4321}.
  3. db_pw에는 가져온 딕셔너리의 'pw' 키에 해당하는 값인 4321이 할당된다.
  4. 이제 db_pw == id_pw[1]를 검사한다. 여기서 id_pw[1]은 9876이고, db_pw는 4321이므로 조건은 거짓이다.
  5. 따라서 함수는 "wrong pw"를 반환한다.

결과적으로 함수 호출 solution([1234, 9876], db)는 "wrong pw"를 반환한다. 입력된 ID와 PW가 주어진 데이터 구조에 저장된 값과 일치하지 않기 때문.