정보처리기사 실기 프로그래밍 기출 파이썬 반복문 연산자 lambda 람다함수 문제 풀이
다음 파이썬 코드의 결과를 적으시오.
a = 100
result = 0
for i in range(1,3):
result = a >> i
result = result + 1
print(result)
result
는 전역변수로, 0으로 초기화되어 있다.
파이썬의 range()
함수는 파라미터로 range(start, stop, step) 이렇게 받을 수 있지만 파라미터를 두 개 받을 경우 range(start, stop-1)이 된다.
따라서 range(1, 3)
은 range(1, 3-1=2)이므로 1부터 2까지의 범위를 가진다.
이때 for문은 i = 1일 때, 그리고 i = 2 일 때를 두번 돌고 결과를 내겠지만, 우리 입장에선 마지막 i의 경우, 즉 i = 2일 때만 보면 된다.
왜냐면 for문 안의 result는 자기 값을 저장하도록 (result = result + 1
) 되어있지만 다시 for문을 돌 때 어차피 a >> i
값으로 대체되기 때문에, 결국 result
는 최종값만 저장하도록 되어있다.
그러면 이제 실제 값을 넣어 계산해보자.
a = 100이고 i = 2인 경우 대입하면 result = 100 >> 2
가 되는데, >> 라는 시프트 연산자*가 있으므로 비트 연산을 위해 10진수인 100을 2진수로 변경해준다.
비트 시프트 연산자 (
>>
,<<
) 계산법*
A >> B
: A를 B만큼 오른쪽에서 지우기
A << B
: A를 B만큼 오른쪽에 채우기
100을 2진수로 변경하면 110100이므로, 110100 >> 2 를 해야한다.
위에 간단히 적은 시프트 연산자 계산법과 같이, 110100을 2만큼 오른쪽에서 지운다. 즉 1101만 남고 오른쪽에 있던 00이 지워지는 거다. 그러면 1101이라는 값이 result
에 담긴다.
result = 1101
다음 식도 대입해서 보자.
result = 1101 + 1
이다. 1101은 2진수이기 때문에 +1할 때 1101에 자리값이 하나 추가된다. 그러면 11010이 된다. 그리고 이 11010을 다시 10진수로 바꾸면 26이 된다.
따라서 정답은 아래와 같다.
26
다음 파이썬 코드의 결과를 적으시오.
dec = 13
bin = ' '
while(dec > 0):
rmd = dec % 2 # 나머지 연산
dec = dec // 2 # 몫 연산 (정수만 취급)
bin = str(rmd) + bin
print(bin)
위 문제는 10진수를 2진수로 변환하는 코드이다.
dec
변수에 담긴 10진수값 13이 양수인 동안 while문 안의 연산을 반복하는데, rmd
에는 2로 나눈 담기고, dec
에는 몫이 담긴다. dec
은 몫을 다시 2로 나누기 위해 필요하고, rmd
는 bin
에 담길 때 str()
함수를 통해 문자열로 변환되어 결과적으로 2진수 값을 저장한다. 문자열의 특성상 값이 나열식으로 더해지기 때문이다.
정답은 아래와 같다.
1101
범위 표기 출력값 작성시*
출력값이[a:b:c]
와 같이 범위 표기(:
)일 경우, 답안도 범위[]
안에 작성해야 한다!
다음 파이썬 코드의 결과를 적으시오.
a = [0, 1, 2, 3, 4, 5, 6]
print(a[:5:2]) # 1
print(a[:1]) # 2
print(a[0]) # 3
위의 파이썬 코드는 간단한 자르기를 수행한다. 하지만 자칫 실수할 수 있기 때문에 출력값을 비교해보기 위해 추가했다.
주석 1, 2, 3을 차례로 보며 출력값을 비교해보자.
a[:5:2]
는 생략된 0을 추가하여 0:5:2로 표기할 수 있으며, 앞에서부터 0부터 5까지의 범위를 2단계로 표기할 것을 의미한다.
a[A부터:B까지:C단계로]
즉, 값으로 나타내면 0부터 4까지의 값 안에서 2단계씩 건너 뛰라는 것이다. 즉, 0, 2, 4가 출력된다.
이때 주의할 것은 a[:5:2]
는 범위를 표기하므로 답안을 작성할 때도 마찬가지로 [0, 2, 4]와 같이 범위로 표기해야 올바른 답이 된다는 것이다.
[0, 2, 4]
a[:1]
는 쉽다. 생략된 0부터 1까지 표기하므로 0만 들어간다. 여기도 마찬가지로 범위 표기이므로 [0]으로 적어야 옳다.
[0]
a[0]
는 범위 표기가 아니다. 즉, a의 0자리 값만을 의미하므로 0으로 표기해야 옳다.
따라서 각 출력값을 적어보면 아래와 같다.
0
다음 파이썬 코드의 결과를 적으시오.
country = ['Korea', 'japan', 'England', 'canada']
print(max(country))
print(max(country, key=lambda i:i.lower()))
위의 문제는 원소를 변경하고 출력값을 추가한 예시 문제이다.
print()를 보면 max함수를 사용한 것을 볼 수 있는데, 이는 연산을 위해 문자열의 첫자를 🔗 아스키(ASCII)코드로 변경한다.
외워야할 아스키(ASCII)코드
A : 65
a : 97
모든 아스키코드값을 아는 것은 당연히 무리이고, 대신 알아야 할 것은 대문자 A는 65이며 순서대로 B 66, C 67 ...과 같이 값이 더해진다는 것, 그리고 소문자 a는 97이며 순서대로 b 98, c 99 ...와 같이 늘어난다는 것이다.
그러면 이제 country의 각 원소들을 보자.
걸러내야 할 것은 대문자 요소들이다. 우리는 max()함수를 통해 최고값을 구할 것이므로 먼저 나오는 대문자 아스키 값들은 절대 답이 될 수 없기 때문이다.
대문자인 'Korea'와 'England'를 걸러내면 남는 것은 소문자인 'japan'과 'canada'인데, 당연히 c보다 j가 뒤에 있으므로 최대값은 j가 될 것이다.
따라서 max(country)의 출력값은 'japan'이 된다.
다음은 max(country, key=lambda i:i.lower())
인데, 여기선 lambda함수가 사용되었다.
lambda 함수도 간단하다. 아래의 예시를 참고하자.
lambda 함수 예시*
a = lambda x : x+1
-> x를 파라미터로 데려오면 x+1 연산을 해주세요.
a(3)
-> lambda의 x = 3이 대입되어 3+1 연산을 해서 반환
똑같이 max함수 내부에 있는 lambda에 적용하면 country가 i에 들어가고 그 값들을 lower()
, 즉 전부 소문자화하여 최대값을 찾게 된다.
그러면 전부 소문자화 한 값중에 가장 큰 값, 알파벳 중에 가장 뒤에 있는 값을 찾으면 된다. 따라서 'Korea'가 된다.
출력값을 정리하면 아래와 같다.
japan
Korea
다음 파이썬 코드의 결과를 적으시오.
count = 0
num = 10
for a in range(1, num+1):
if num == a:
count += 1
elif num % a == 0:
count -= 1
print(count)
이런 반복문과 조건식이 있는 코드는 목적이 있다. 이 for문을 통해 특정한 규칙을 찾고자 한다는 것이다.
위의 코드는 10을 n으로 나눌 때 나누어 떨어지는 개수를 찾고자 한다. 더 명확히 말하면 1~10 사이의 수 중에서 10으로 나누었을 때 나누어 떨어지는 개수 + 1의 값을 출력하는 코드이다.
코드를 한줄씩 보면서 해석해보자.
우선 for문의 range()
함수에서는 1부터 n+1즉, 11의 값까지를 범위로 한다고 했으므로, range함수 특성상 (1, 11-1)의 범위를 말한다.
따라서 a의 범위는 1부터 10까지가 된다.
if문으로 가보면, if문은 마지막에만 탄다고 보고 elif
로 넘어가야 한다. 그 이유는 num == a
일 경우는 num=10이 a와 같을 경우인데, for문의 마지막에서야 이 조건이 참이될 것이기 때문이다.
따라서 우리는 계속 elif
만 돈다고 생각하면 된다.
elif
를 보면, num % a == 0
즉 num=10을 a로 나눈 나머지가 0인 경우를 의미하는데, 그러면 10을 나머지 없이 나눌 수 있는 수를 찾으면 끝난다.
1~9중에서 찾아야 하므로 1, 2, 5가 끝이다. count -= 1
해줘야 하므로 count = -3이 된다.
이제 위에서 말한 마지막 조건인, a=10일 때의 if 조건식으로 가면 count += 1
하라고 되어있다. 즉 -3에서 +1을 하라는 뜻이다.
정답은 아래와 같다.
-2
🙋🏻 참고한 곳
🔗 홍달쌤 유튜브 🔗 홍달쌤의 정보처리기사 실기 책