
Python 연산자
Python 연산자(Operators)는 변수와 값에 대해 특정 연산을 수행하는 특수 기호나 키워드다. 연산자는 프로그래밍의 핵심 구성 요소로서 수학적 계산, 값 비교, 논리 판단, 비트 조작, 멤버십 검사 등 모든 데이터 처리 작업의 기반이 된다. Python은 직관적이고 강력한 연산자 체계를 제공하여 복잡한 연산을 간결하게 표현할 수 있게 한다.
연산자는 피연산자(operand)에 작용하여 결과를 생성한다. 예를 들어 3 + 5에서 +는 연산자이고, 3과 5는 피연산자다. Python의 연산자는 우선순위와 결합성을 가지며, 이를 정확히 이해하는 것은 복잡한 표현식을 올바르게 계산하는 데 필수적이다.
산술 연산자
산술 연산자는 수학적 계산을 수행하는 가장 기본적인 연산자들이다. Python은 전통적인 수학 연산뿐만 아니라 몫과 나머지를 구하는 특수 연산도 제공한다.
연산자 | 이름 | 설명 | 예시 | 결과 |
---|---|---|---|---|
+ | 덧셈 | 두 값을 더한다 | 15 + 4 | 19 |
– | 뺄셈 | 첫 번째 값에서 두 번째 값을 뺀다 | 15 – 4 | 11 |
* | 곱셈 | 두 값을 곱한다 | 15 * 4 | 60 |
/ | 나눗셈 | 나눗셈 결과를 실수로 반환한다 | 15 / 4 | 3.75 |
// | 몫 | 나눗셈의 몫만 반환한다 (소수점 버림) | 15 // 4 | 3 |
% | 나머지 | 나눗셈의 나머지를 반환한다 | 15 % 4 | 3 |
** | 거듭제곱 | 첫 번째 값을 두 번째 값만큼 거듭제곱한다 | 15 ** 4 | 50625 |
a = 15
b = 4
print(f"덧셈: {a} + {b} = {a + b}")
print(f"뺄셈: {a} - {b} = {a - b}")
print(f"곱셈: {a} * {b} = {a * b}")
print(f"나눗셈: {a} / {b} = {a / b}")
print(f"몫: {a} // {b} = {a // b}")
print(f"나머지: {a} % {b} = {a % b}")
print(f"거듭제곱: {a} ** {b} = {a ** b}")
위 코드는 각각 19, 11, 60, 3.75, 3, 3, 50625를 출력한다.
할당 연산자
할당 연산자는 변수에 값을 저장하거나 기존 값을 수정하는 데 사용된다. 복합 할당 연산자는 연산과 할당을 동시에 수행하여 코드를 간결하게 만든다.
연산자 | 예시 | 동일한 표현 | 설명 |
---|---|---|---|
= | x = 5 | x = 5 | 변수에 값을 할당한다 |
+= | x += 3 | x = x + 3 | 값을 더하고 할당한다 |
-= | x -= 3 | x = x – 3 | 값을 빼고 할당한다 |
*= | x *= 3 | x = x * 3 | 값을 곱하고 할당한다 |
/= | x /= 3 | x = x / 3 | 값을 나누고 할당한다 |
//= | x //= 3 | x = x // 3 | 몫을 계산하고 할당한다 |
%= | x %= 3 | x = x % 3 | 나머지를 계산하고 할당한다 |
**= | x **= 3 | x = x ** 3 | 거듭제곱을 계산하고 할당한다 |
x = 10
print(f"초기값: x = {x}")
x += 5
print(f"x += 5: x = {x}")
x *= 2
print(f"x *= 2: x = {x}")
x //= 3
print(f"x //= 3: x = {x}")
x **= 2
print(f"x **= 2: x = {x}")
위 코드는 x 변수의 변화 과정을 단계별로 출력한다.
비교 연산자
비교 연산자는 두 값을 비교하여 불린(True/False) 결과를 반환한다. 조건문과 반복문에서 핵심적인 역할을 담당한다.
연산자 | 이름 | 설명 | 예시 | 결과 |
---|---|---|---|---|
== | 같음 | 두 값이 같으면 True를 반환한다 | 5 == 5 | True |
!= | 같지 않음 | 두 값이 같지 않으면 True를 반환한다 | 5 != 3 | True |
> | 보다 큼 | 왼쪽 값이 오른쪽 값보다 크면 True를 반환한다 | 5 > 3 | True |
< | 보다 작음 | 왼쪽 값이 오른쪽 값보다 작으면 True를 반환한다 | 3 < 5 | True |
>= | 크거나 같음 | 왼쪽 값이 오른쪽 값보다 크거나 같으면 True를 반환한다 | 5 >= 5 | True |
<= | 작거나 같음 | 왼쪽 값이 오른쪽 값보다 작거나 같으면 True를 반환한다 | 3 <= 5 | True |
a = 10
b = 5
print(f"{a} == {b}: {a == b}")
print(f"{a} != {b}: {a != b}")
print(f"{a} > {b}: {a > b}")
print(f"{a} <= {b}: {a <= b}")[/code]
연쇄 비교
Python은 수학적 표현과 유사한 연쇄 비교를 지원한다. 이는 범위 검사에서 특히 유용하다.
[code lang="python"]age = 25
print(f"18 <= {age} < 65: {18 <= age < 65}")
score = 85
print(f"80 <= {score} < 90: {80 <= score < 90}")[/code]
논리 연산자
논리 연산자는 불린 값들을 조합하여 복합적인 조건을 만든다. 단락 평가(short-circuit evaluation)를 수행하여 효율성을 높인다.
연산자
설명
예시
결과
and
두 조건이 모두 True이면 True를 반환한다
True and False
False
or
두 조건 중 하나라도 True이면 True를 반환한다
True or False
True
not
조건의 불린 값을 반대로 바꾼다
not True
False
[code lang="python"]x = 6
print(f"(x > 3) and (x < 10): {(x > 3) and (x < 10)}")
print(f"(x > 10) or (x < 5): {(x > 10) or (x < 5)}")
print(f"not (x > 5): {not (x > 5)}")
단락 평가
Python의 논리 연산자는 단락 평가를 수행한다. 결과가 확실해지면 나머지 조건을 평가하지 않아 성능을 최적화한다.
def expensive_function():
print("비싼 연산 실행됨")
return True
result1 = False and expensive_function()
print(f"Result1: {result1}")
result2 = True or expensive_function()
print(f"Result2: {result2}")
위 코드에서 expensive_function()은 한 번도 호출되지 않는다.
식별 연산자
식별 연산자는 두 변수가 같은 객체를 참조하는지 확인한다. 값의 동등성이 아닌 메모리상의 동일성을 검사한다.
연산자 | 설명 | 용도 |
---|---|---|
is | 두 변수가 동일한 객체를 참조하면 True를 반환한다 | 객체 동일성 검사 |
is not | 두 변수가 동일한 객체를 참조하지 않으면 True를 반환한다 | 객체 비동일성 검사 |
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(f"a == b: {a == b}")
print(f"a is b: {a is b}")
print(f"a is c: {a is c}")
print(f"a is not b: {a is not b}")
💡 == vs is 차이점:
• == 는 값의 동등성을 비교한다 (내용이 같은가?)
• is 는 객체의 동일성을 비교한다 (같은 메모리 위치인가?)
• None, True, False와의 비교에는 is를 사용한다
• 일반적인 값 비교에는 ==를 사용한다
멤버십 연산자
멤버십 연산자는 특정 시퀀스나 컬렉션에 값이 포함되어 있는지 확인한다.
연산자 | 설명 | 예시 | 결과 |
---|---|---|---|
in | 시퀀스 내에 지정된 값이 있으면 True를 반환한다 | "py" in "python" | True |
not in | 시퀀스 내에 지정된 값이 없으면 True를 반환한다 | "js" not in "python" | True |
fruits = ["apple", "banana", "cherry"]
text = "Hello World"
print(f"'apple' in fruits: {'apple' in fruits}")
print(f"'orange' not in fruits: {'orange' not in fruits}")
print(f"'World' in text: {'World' in text}")
print(f"'hello' not in text: {'hello' not in text}")
비트 연산자
비트 연산자는 정수의 이진 표현에서 비트 단위로 연산을 수행한다. 저수준 프로그래밍이나 플래그 관리에서 활용된다.
연산자 | 이름 | 설명 | 예시 | 결과 |
---|---|---|---|---|
& | AND | 두 비트가 모두 1이면 1을 반환한다 | 6 & 3 | 2 |
| | OR | 두 비트 중 하나라도 1이면 1을 반환한다 | 6 | 3 | 7 |
^ | XOR | 두 비트가 서로 다르면 1을 반환한다 | 6 ^ 3 | 5 |
~ | NOT | 모든 비트를 반전시킨다 | ~6 | -7 |
<< | 왼쪽 시프트 | 비트를 왼쪽으로 이동시킨다 | 6 << 1 | 12 |
>> | 오른쪽 시프트 | 비트를 오른쪽으로 이동시킨다 | 6 >> 1 | 3 |
x = 6 # 이진수: 110
y = 3 # 이진수: 011
print(f"x & y = {x & y}") # 2 (010)
print(f"x | y = {x | y}") # 7 (111)
print(f"x ^ y = {x ^ y}") # 5 (101)
print(f"~x = {~x}") # -7
print(f"x << 1 = {x << 1}") # 12 (1100)
print(f"x >> 1 = {x >> 1}") # 3 (11)
연산자 우선순위
연산자 우선순위는 복잡한 표현식에서 연산 순서를 결정한다. 괄호를 사용하여 명시적으로 순서를 지정하는 것이 좋다.
우선순위 | 연산자 | 설명 | 결합성 |
---|---|---|---|
1 (최고) | () | 괄호 | 좌→우 |
2 | ** | 거듭제곱 | 우→좌 |
3 | +x, -x, ~x | 단항 연산자 | 우→좌 |
4 | *, /, //, % | 곱셈, 나눗셈 | 좌→우 |
5 | +, - | 덧셈, 뺄셈 | 좌→우 |
6 | <<, >> | 비트 시프트 | 좌→우 |
7 | & | 비트 AND | 좌→우 |
8 | ^ | 비트 XOR | 좌→우 |
9 | | | 비트 OR | 좌→우 |
10 | ==, !=, <, <=, >, >=, is, is not, in, not in | 비교, 식별, 멤버십 연산자 | 좌→우 |
11 | not | 논리 NOT | 우→좌 |
12 | and | 논리 AND | 좌→우 |
13 (최저) | or | 논리 OR | 좌→우 |
result1 = 2 + 3 * 4
result2 = (2 + 3) * 4
result3 = 2 ** 3 ** 2
result4 = (2 ** 3) ** 2
print(f"2 + 3 * 4 = {result1}") # 14
print(f"(2 + 3) * 4 = {result2}") # 20
print(f"2 ** 3 ** 2 = {result3}") # 512
print(f"(2 ** 3) ** 2 = {result4}") # 64
실무 활용 예제
연산자들을 조합한 실제 프로그래밍 패턴들을 살펴보자.
사용자 입력 검증
def validate_user_input(username, password, age):
"""사용자 입력 데이터 종합 검증"""
is_valid_username = len(username) >= 3 and username.isalnum()
is_valid_password = len(password) >= 8
is_valid_age = isinstance(age, int) and 13 <= age <= 120
all_valid = is_valid_username and is_valid_password and is_valid_age
return {
'username_valid': is_valid_username,
'password_valid': is_valid_password,
'age_valid': is_valid_age,
'all_valid': all_valid
}
result = validate_user_input("user123", "password123", 25)
print(f"검증 결과: {result}")[/code]
플래그 기반 권한 관리
[code lang="python"]READ = 1 # 001
WRITE = 2 # 010
EXECUTE = 4 # 100
def check_permission(user_permissions, required_permission):
"""비트 마스크를 사용한 권한 검사"""
return (user_permissions & required_permission) == required_permission
def grant_permission(current_permissions, new_permission):
"""새로운 권한 부여"""
return current_permissions | new_permission
def revoke_permission(current_permissions, permission_to_remove):
"""권한 제거"""
return current_permissions & ~permission_to_remove
user_permissions = READ | WRITE # 011 (읽기 + 쓰기)
print(f"읽기 권한: {check_permission(user_permissions, READ)}")
print(f"실행 권한: {check_permission(user_permissions, EXECUTE)}")
user_permissions = grant_permission(user_permissions, EXECUTE)
print(f"실행 권한 부여 후: {check_permission(user_permissions, EXECUTE)}")
user_permissions = revoke_permission(user_permissions, WRITE)
print(f"쓰기 권한 제거 후: {check_permission(user_permissions, WRITE)}")
조건부 처리 최적화
def process_data(data, options=None):
"""효율적인 조건부 데이터 처리"""
if not data or not isinstance(data, list):
return None
options = options or {}
# 단락 평가를 활용한 안전한 처리
filter_func = options.get('filter')
transform_func = options.get('transform')
result = data
if filter_func and callable(filter_func):
result = [item for item in result if filter_func(item)]
if transform_func and callable(transform_func):
result = [transform_func(item) for item in result]
return result
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_doubled = process_data(numbers, {
'filter': lambda x: x % 2 == 0,
'transform': lambda x: x * 2
})
print(f"짝수를 2배로: {even_doubled}")
💡 연산자 활용 모범 사례:
• 복잡한 표현식에서는 괄호를 사용하여 의도를 명확히 한다
• 논리 연산자의 단락 평가를 활용하여 성능을 최적화한다
• is 연산자는 None, True, False와의 비교에만 사용한다
• 복합 할당 연산자(+=, -=)를 활용하여 코드를 간결하게 만든다
• 연쇄 비교를 활용하여 범위 검사를 직관적으로 표현한다
• 멤버십 연산자를 활용하여 포함 관계를 명확히 검사한다
• 비트 연산자는 플래그나 권한 관리에서 효과적으로 활용한다
• 조건식을 적절히 사용하여 간단한 조건부 할당을 처리한다
Python의 연산자 체계는 프로그래밍의 기본 도구로서 다양한 데이터 조작과 논리 처리를 가능하게 한다. 각 연산자의 특성과 우선순위를 정확히 이해하고 적절히 조합하면, 효율적이고 가독성 높은 코드를 작성할 수 있다. 특히 단락 평가, 연쇄 비교, 비트 마스킹 등 Python의 고유한 특성을 활용하면 더욱 파이썬다운 코드를 구현할 수 있으며, 성능과 안전성을 동시에 확보할 수 있다.