and·or·not은 조건의 참(True)과 거짓(False)을 잇거나 뒤집는 논리 연산자(logical operator)입니다. and는 양쪽이 모두 참일 때만, or는 한쪽이라도 참이면 참이고, not은 참과 거짓을 뒤집습니다.
청소년 요금은 13세 이상이면서 19세 이하일 때 붙습니다. 비교 하나로는 이런 범위를 적을 수 없어서 비교 둘을 and로 잇습니다.
그리고 and·or는 왼쪽만 보고 답이 정해지면 오른쪽을 아예 계산하지 않습니다. 이 성질은 오류를 막는 데에도 씁니다.
1and는 둘 다 참일 때만 참
age >= 13 and age <= 19는 비교 둘을 and로 이은 식입니다.
비교가 and보다 먼저 묶이므로 괄호가 없어도 됩니다. 왼쪽 비교부터 True·False로 접히고, 필요하면 오른쪽 비교도 접힌 뒤 and가 둘을 하나로 잇습니다. 오른쪽이 필요 없을 때는 4절에서 봅니다.
age = 15
print(age >= 13 and age <= 19)
age = 25
print(age >= 13 and age <= 19)
True
False25세는 왼쪽 25 >= 13이 True이지만 오른쪽 25 <= 19가 False라서 전체가 False입니다.
and와 or의 결과를 모두 적으면 이렇습니다.
| 왼쪽 | 오른쪽 | and | or |
|---|---|---|---|
True | True | True | True |
True | False | False | True |
False | True | False | True |
False | False | False | False |
2or는 한쪽이라도 참이면 참
카페가 회원이거나 1만 원 이상 주문한 손님에게 쿠키를 준다고 합시다.
member = False
total = 14500
print(member or total >= 10000)
Truemember는 False이지만 오른쪽 14500 >= 10000이 True라서 전체가 True입니다. or는 양쪽이 모두 False일 때만 False입니다.
3not과 섞어 쓸 때의 차례
not은 뒤에 오는 참·거짓을 뒤집습니다. not True는 False, not False는 True입니다.
member = False
print(not member)
if not member:
print('회원 가입 안내')
True
회원 가입 안내여럿을 섞어 쓰면 계산(+·- 등)과 비교가 먼저 묶이고, 그다음 not → and → or 차례로 묶입니다.
차례가 헷갈리면 괄호로 묶어 보입니다. 아래 '예제'처럼 조건을 나눠 그 값에 이름을 붙이면, 한 줄에 논리 연산자가 하나씩만 들어 읽기 쉽습니다.
4왼쪽만으로 답이 정해지면 오른쪽은 계산하지 않는다
and는 왼쪽이 False면 오른쪽이 무엇이든 False입니다. 그래서 파이썬은 오른쪽을 계산하지 않고 바로 False를 냅니다.
or는 왼쪽이 True면 오른쪽을 보지 않고 바로 True를 냅니다.
공식 자습서는 이런 연산자를 단락-회로(short-circuit) 연산자라고 부릅니다.
왼쪽만으로 답이 정해지지 않으면 오른쪽을 계산하고, 그 오른쪽 값이 그대로 전체의 값이 됩니다.
그래서 오른쪽에 비교 대신 수가 있으면, 전체의 값도 True·False가 아닌 그 수입니다.
print(False or 2)
if 2:
print('2는 참')
2
2는 참1번 줄은 왼쪽이 False라서 오른쪽 2가 그대로 전체의 값이 됩니다. 조건 자리에 수가 오면 파이썬은 0을 거짓으로, 0이 아닌 수를 참으로 치므로 2번 줄의 조건은 참입니다.
0으로 나누면 ZeroDivisionError가 납니다. 아래 코드는 무엇을 찍을까요? 답을 정한 뒤 펼쳐 보세요.
print(True or 1 / 0)
실행 결과 보기
True예상과 다르면 그곳이 배울 곳입니다.
왼쪽이 True라서 or의 답은 이미 True입니다. 오른쪽 1 / 0은 계산되지 않아 오류도 나지 않습니다.
이 성질로 오류를 막습니다. 아래 n은 오늘 주문 수입니다. 주문이 0건이면 평균(total / n)을 내는 순간 0으로 나누게 됩니다.
n = 0
total = 0
if n > 0 and total / n >= 4000:
print('좋은 날')
else:
print('기록 부족')
기록 부족n > 0이 False라서 오른쪽 나누기는 실행되지 않고, else 갈래로 갑니다.
두 비교의 차례를 바꿔 나누기를 왼쪽에 두면, 나누기부터 계산하다 ZeroDivisionError로 멈춥니다.
예제
청소년이거나 회원이면 커피를 500원 싸게 팝니다. 고르기의 세 걸음(1. 조건 세우기 · 2. 갈래마다 할 일 · 3. 갈래 뒤 공통)으로 썼습니다.
age = 15
member = False
# 1. 조건 세우기
teen = age >= 13 and age <= 19
cheap = teen or member
# 2. 갈래마다 할 일
if cheap:
price = 3500
else:
price = 4000
# 3. 갈래 뒤 공통
print(f'커피 {price:,}원')
커피 3,500원- 1. 조건 세우기: 청소년인지를
and로 이은 값에 깃발teen을, 할인 대상인지를or로 이은 값에 깃발cheap을 붙입니다. 15세라teen은True이고,cheap은True or False라서True입니다. - 2. 갈래마다 할 일:
cheap이True면 3,500원에, 아니면 4,000원에price를 붙입니다. - 3. 갈래 뒤 공통: 어느 갈래를 지났든 커피 값을 찍습니다.
자주 틀리는 곳
틀린 생각: and·or는 늘 양쪽을 다 계산한 뒤 답을 낸다.
+·- 같은 계산은 양쪽 값을 다 구해야 답이 나오므로, and·or도 그럴 것처럼 보입니다. 그러나 오른쪽에 0으로 나누기가 있어도 오류가 나지 않습니다.
print(False and 1 / 0)
print(True or 1 / 0)
False
True1번 줄은 왼쪽 False만으로, 2번 줄은 왼쪽 True만으로 답이 정해져 오른쪽 1 / 0을 계산하지 않았습니다.
맞는 규칙: and는 왼쪽이 거짓이면, or는 왼쪽이 참이면 답이 정해져 오른쪽을 계산하지 않습니다. 그래서 오류가 날 수 있는 계산은 그것을 막는 비교의 오른쪽에 둡니다.
틀린 생각: x == 1 or 2는 'x가 1이나 2인가'를 묻는다.
말로 'x가 1이나 2인가'라고 할 때는 x를 한 번만 말합니다. 그러나 or의 양쪽은 따로 계산되고, 오른쪽 2는 비교가 아니라 수 하나입니다.
x = 3
print(x == 1 or 2)
if x == 1 or 2:
print('1이나 2')
2
1이나 22번 줄의 or는 왼쪽 3 == 1이 False라 오른쪽 값 2를 그대로 내놓습니다(4절). 조건 자리의 수는 0이 아니면 참으로 치므로, 3번 줄의 조건은 x가 무엇이든 늘 참입니다.
맞는 규칙: or는 왼쪽이 거짓이면 오른쪽 값을 그대로 내놓아서, 오른쪽에 수만 두면 그 수가 조건이 됩니다. 그래서 양쪽에 비교를 다 써서 x == 1 or x == 2로 묻습니다.
틀린 생각: and 뒤에서는 앞에 쓴 age를 다시 쓰지 않아도 된다.
'13 이상이고 19 이하'도 말로는 나이를 한 번만 말합니다. 그러나 and의 양쪽은 따로 계산되는 식이라, <= 19만으로는 식이 되지 않습니다.
age = 15
print(age >= 13 and <= 19)
File "main.py", line 2 print(age >= 13 and <= 19) ^^SyntaxError: invalid syntax^^가 and 바로 뒤의 <= 기호를 가리킵니다. and 뒤에는 새 식이 와야 하는데 <= 기호부터 시작했습니다.
맞는 규칙: and·or의 양쪽은 저마다 값 하나로 접히는 완전한 식이어야 합니다. 그래서 오른쪽에도 이름을 다시 써서 age >= 13 and age <= 19로 씁니다.
확인 문제
1. 예제의 age를 20으로 바꿨습니다. 무엇이 찍히는지 그대로 쓰세요.
age = 20
member = False
# 1. 조건 세우기
teen = age >= 13 and age <= 19
cheap = teen or member
# 2. 갈래마다 할 일
if cheap:
price = 3500
else:
price = 4000
# 3. 갈래 뒤 공통
print(f'커피 {price:,}원')
힌트
'1. 조건 세우기' — teen의 비교 둘을 하나씩 접은 뒤 and로 잇습니다.
정답
커피 4,000원20 >= 13은 True이지만 20 <= 19가 False라서 teen은 False입니다. cheap은 False or False라서 False이고, else 갈래에서 price가 4,000원에 붙습니다.
흔한 오답은 커피 3,500원입니다. 왼쪽 비교 하나가 참이라 and 전체가 참이라고 본 것입니다. and는 둘 다 참일 때만 참입니다.
2. 할인 규칙을 바꿉니다. 65세 이상이면 senior가 True, 65세 이상이거나 회원이면 cheap이 True입니다. 빈칸으로 남은 '1. 조건 세우기'의 두 줄을 쓰고, 이 코드가 무엇을 찍는지도 쓰세요.
age = 70
member = False
# 1. 조건 세우기
____
____
# 2. 갈래마다 할 일
if cheap:
price = 3500
else:
price = 4000
# 3. 갈래 뒤 공통
print(f'커피 {price:,}원')
힌트
'1. 조건 세우기' — 첫 줄은 비교 하나의 값에 senior를 붙이고, 둘째 줄은 '이거나'를 논리 연산자로 옮깁니다.
정답
age = 70
member = False
# 1. 조건 세우기
senior = age >= 65
cheap = senior or member
# 2. 갈래마다 할 일
if cheap:
price = 3500
else:
price = 4000
# 3. 갈래 뒤 공통
print(f'커피 {price:,}원')커피 3,500원70세라 senior가 True이고, cheap은 True or False라서 True입니다.
다르게 써도 되는 곳: cheap = member or senior처럼 or의 양쪽을 바꿔 써도 같습니다. 나이를 정수로 적으므로 senior = age > 64도 같은 범위입니다.
흔한 오답은 cheap = senior and member입니다. and도 양쪽 가운데 하나만 참이면 참이라고 본 것입니다. and는 둘 다 참일 때만 참이라, 회원이 아닌 70세는 할인을 받지 못해 커피 4,000원이 찍힙니다. senior = age > 65는 70세에서는 같은 줄을 찍어도 65세를 빼므로 맞는 답이 아닙니다. 두 줄을 합친 cheap = age >= 65 or member도 찍히는 결과는 같지만, 이 문제가 바라는 senior는 생기지 않습니다.
3. 마트 앱이 주말에만 할인을 보이려 합니다. 요일은 월요일 1부터 일요일 7까지 수로 적습니다. 그런데 수요일(3)에도 주말 할인이 찍힙니다.
day = 3
if day == 6 or 7:
print('주말 할인')
else:
print('평일 가격')
주말 할인몇 번 줄을 어떻게 고쳐야 할까요?
힌트
2번 줄에서 or의 왼쪽과 오른쪽이 각각 무엇인지 보세요.
정답
2번 줄을 if day == 6 or day == 7:로 고칩니다.
day = 3
if day == 6 or day == 7:
print('주말 할인')
else:
print('평일 가격')평일 가격고치기 전에는 or 오른쪽이 비교가 아니라 수 7이었습니다. day == 6이 거짓이면 or가 7을 그대로 내놓고, 0이 아닌 수는 참으로 치므로 조건 전체가 늘 참이었습니다.
다르게 고쳐도 되는 곳: 요일이 1~7뿐이라 if day >= 6:이나 if day > 5:로 고쳐도 일곱 요일 모두 맞게 찍힙니다.
흔한 오답은 day == 6 and day == 7입니다. 말로 '토요일과 일요일'이라 하듯 and로 이으면 두 날 가운데 하루면 참이라고 본 것입니다. 하루가 토요일이면서 일요일일 수는 없어서 이 조건은 늘 거짓이고, 주말에도 평일 가격이 찍힙니다.
아래 코드 2·3번 줄의 or 2를 모두 or 0으로 바꾸면 찍히는 줄을 봅니다.
처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.