Python의 연산자 및 표현식

2023. 12. 9. 20:32python/basic

Python의 비교 연산자 및 표현식

부동 소수점 값 비교

x = 1.1 + 2.2
x == 3.3
False
1.1 + 2.2
3.3000000000000003

float 객체에 저장된 값은 여러분이 생각하는 것과 정확하게 일치하지 않을 수도 있습니다. 따라서 == 연산자를 사용하여 부동 소수점 값이 완전히 동일한지 비교하는 것은 좋지 않습니다.

두 개의 부동 소수점 값이 동일한지 확인하는 가장 좋은 방법은 어느 정도 허용 오차가 허용되는 한 두 부동 소수점 값이 서로 가까운지 확인하는 것입니다.표준 라이브러리의 math 모듈은 비교에 도움이 되는 isclose()라는 함수를 편리하게 제공합니다. 이 함수는 두 개의 숫자를 가져와 대략적인 동등성을 테스트합니다.

from math import isclose

x = 1.1 + 2.2

isclose(x, 3.3)
True

문자열 비교

비교에는 사전순 정렬이 사용됩니다. 이는 Python이 각 문자열의 첫 번째 항목을 비교한다는 의미입니다.

"Hello" > "HellO"
True

길이가 다른 문자열을 비교할 수도 있습니다. 이 예에서 Python은 평소와 같이 문자별 비교를 실행합니다. 문자가 부족하면 짧은 문자열이 긴 문자열보다 적습니다. 이는 또한 빈 문자열이 가능한 가장 작은 문자열임을 의미합니다.

"Hello" > "Hello, World!"
False

리스트와 튜플의 비교

== 및 != 연산자를 사용하여 목록을 튜플과 실제로 비교할 수 있다는 점에 유의하는 것이 중요합니다. 하지만 <, >, <= 및 >= 연산자는 비교할 수 없습니다 <, >, <= 및 >= 연산자

print([2,3] == (2,3))
print([2,3] != (2,3))
print([2, 3] > (2, 3))
False
True
TypeError: '>' not supported between instances of 'list' and 'tuple'
print([2, 3] <= (2, 3))
TypeError: '<=' not supported between instances of 'list' and 'tuple'

Python의 부울 연산자 및 표현식

부울 피연산자를 포함하는 부울 표현식

age = 20

is_adult = age > 18
print(is_adult)

print(type(is_adult))
True
<class 'bool'>

부울 값을 반환하는 Python 내장 함수와 사용자 정의 함수도 찾을 수 있습니다. 이러한 유형의 함수를 조건자 함수라고 합니다. 내장된 all(), any(), callable() 및 isinstance() 함수는 모두 좋은 예입니다.

number = 42

validation_conditions = (
    isinstance(number, int),
    number % 2 == 0,
)

print(all(validation_conditions))

print(callable(number))

print(callable(print))
True
False
True

이 코드 스니펫에서는 먼저 오랜 친구의 할당 연산자를 사용하여 number이라는 변수를 정의합니다. 그런 다음 validation_conditions라는 또 다른 변수를 만듭니다. 이 변수는 표현식의 튜플을 보유합니다. 첫 번째 표현식은 isinstance()을 사용하여 number가 정수 값인지 확인합니다.

두 번째는 모듈로(%) 연산자와 항등(==) 연산자를 결합하여 입력 값이 유효한지 확인하는 조건을 만드는 복합 표현식입니다. 짝수입니다. 이 조건에서 모듈로 연산자는 number을 2로 나눈 나머지를 반환하고 항등 연산자는 그 결과를 0와 비교합니다. True 또는 False을 비교 결과로 반환합니다.

그런 다음 all() 함수를 사용하여 모든 조건이 참인지 확인합니다. 이 예에서는 number = 42이므로 조건이 true이고 all()은 True를 반환합니다. 약간의 실험을 원한다면 number의 값을 가지고 놀 수 있습니다.

마지막 두 예에서는 callable() 함수를 사용합니다. 이름에서 알 수 있듯이 이 함수를 사용하면 객체가 호출 가능인지 여부를 확인할 수 있습니다. 호출 가능하다는 것은 Python 함수를 호출하는 것처럼 한 쌍의 괄호와 적절한 인수를 사용하여 객체를 호출할 수 있다는 의미입니다.

number 변수는 호출할 수 없으며 그에 따라 함수는 False를 반환합니다. 반면에 print() 함수는 호출 가능하므로 callable()는 True를 반환합니다.

부울 컨텍스트에서 일반 객체 평가

기본적으로 객체의 클래스가 또는 bool() 메서드를 정의하지 않는 한 객체는 true로 간주됩니다. > 객체와 함께 호출되면 0을 반환하는 메서드입니다. 거짓으로 간주되는 대부분의 내장 개체는 다음과 같습니다.

  • false로 정의된 상수: None 및 False.
  • 모든 숫자 유형의 0: 0, 0.0, 0j, Decimal(0) , Fraction(0, 1)
  • 빈 시퀀스 및 컬렉션: ’’, (), [], {}, set(), range(0)

객체를 인수로 사용하여 내장된 bool() 함수를 호출하여 객체의 진리값을 확인할 수 있습니다. bool()가 True를 반환하면 해당 개체는 진실입니다. bool()가 False를 반환하면 거짓입니다.

숫자 값의 경우 0 값은 거짓이고 0이 아닌 값은 진실입니다.

bool(0), bool(0.0), bool(0.0+0j)
(False, False, False)
bool(-3), bool(3.14159), bool(1.0+1j)
(True, True, True)

Python은 모든 숫자 유형의 0 값을 거짓으로 간주합니다. 다른 모든 값은 0에 얼마나 가까운지에 관계없이 진실입니다.

문자열을 평가할 때 빈 문자열은 항상 거짓이고 비어 있지 않은 문자열은 진실입니다. 공백이 포함된 문자열도 Python의 눈에는 진실이라는 점에 유의하세요.

print(bool(""))
print(bool(" "))
print(bool("Hello"))
False
True
True

마지막으로 목록, 튜플, 세트 및 와 같은 내장 컨테이너 데이터 유형 사전은 비어 있으면 거짓입니다. 그렇지 않으면 Python은 이를 진실한 객체로 간주합니다.

print(bool([]))
print(bool([1, 2, 3]))

print(bool(()))
print(bool(("John", 25, "Python Dev")))

print(bool(set()))
print(bool({"square", "circle", "triangle"}))

print(bool({}))
print(bool({"name": "John", "age": 25, "job": "Python Dev"}))
False
True
False
True
False
True
False
True

다른 유형의 피연산자를 포함하는 부울 표현식

참고: 두 개의 부울 피연산자를 결합하는 부울 표현식은 보다 일반적인 규칙의 특별한 경우입니다. 이를 통해 모든 종류의 피연산자와 함께 논리 연산자를 사용할 수 있습니다. 모든 경우에 결과적으로 피연산자 중 하나를 얻게 됩니다.

Python에서는 숫자 유형의 0 값이 거짓이라는 점을 기억하십시오. 나머지 값은 진실입니다.

print(3 and 4)

print(0 and 4)

print(3 and 0)
4
0
0
print(3 or 4)

print(0 or 4)

print(3 or 0)
3
4
3

x or y과 같은 표현식은 x 또는 y 중 하나가 참이면 참이고, 둘 다이면 거짓입니다. 는 거짓입니다. 이 유형의 표현식은 찾은 첫 번째 실제 피연산자를 반환합니다. 두 피연산자가 모두 거짓이면 표현식은 오른쪽 피연산자를 반환합니다.

0 or []
[]
print(not 3)
print(not 0)
False
True

복합 논리식 및 단락 평가

단락 평가를 설명하기 위해 식별 함수, f()가 있다고 가정합니다.

  • 단일 인수를 사용합니다.
  • 함수와 인수를 화면에 표시합니다.
  • 인수를 반환 값으로 반환합니다.
def f(arg):
    print(f"-> f({arg}) = {arg}")
    return arg

print(f(0))

print(f(False))

print(f(1.5))
-> f(0) = 0
0
-> f(False) = False
False
-> f(1.5) = 1.5
1.5
f(0) or f(False) or f(1) or f(2) or f(3)
-> f(0) = 0
-> f(False) = False
-> f(1) = 1
1

이 예에서 Python은 먼저 f(0)를 평가하고 0를 반환합니다. 이 값은 거짓입니다. 표현식이 아직 참이 아니므로 평가는 왼쪽에서 오른쪽으로 계속됩니다. 다음 피연산자 f(False)는 False를 반환합니다. 해당 값도 거짓이므로 평가가 계속됩니다.

다음은 f(1)입니다. 이는 1로 평가되며 이는 사실입니다. 그 시점에서 Python은 전체 표현식이 참이라는 것을 이미 알고 있기 때문에 평가를 중지합니다. 결과적으로 Python은 1을 표현식의 값으로 반환하고 나머지 피연산자 f(2) 및 f(3)를 평가하지 않습니다. 출력에서 f(2) 및 f(3) 호출이 발생하지 않음을 확인할 수 있습니다.

f(1) and f(False) and f(2) and f(3)
-> f(1) = 1
-> f(False) = False
False
print(f(1) and f(0.0) and f(2) and f(3))
-> f(1) = 1
-> f(0.0) = 0.0
0.0

이 예에서 단락 평가는 피연산자가 거짓이 되는 즉시 Python이 평가를 중지하도록 지시합니다. 그 시점에서는 전체 표현이 거짓인 것으로 알려져 있습니다. 그런 경우 Python은 피연산자 평가를 중지하고 평가를 종료한 잘못된 피연산자를 반환합니다.

모든 피연산자가 참이면 Python은 피연산자를 모두 평가하고 마지막(가장 오른쪽) 피연산자를 표현식 값으로 반환합니다.

f(1) and f(2.2) and f("Hello")
-> f(1) = 1
-> f(2.2) = 2.2
-> f(Hello) = Hello
'Hello'
f(1) and f(2.2) and f(0)
-> f(1) = 1
-> f(2.2) = 2.2
-> f(0) = 0
0

첫 번째 예에서는 모든 피연산자가 진실입니다. 표현식도 진실이며 마지막 피연산자를 반환합니다. 두 번째 예에서는 마지막 피연산자를 제외한 모든 피연산자가 진실입니다. 표현식이 거짓이며 마지막 피연산자를 반환합니다.

단락 평가를 활용하는 관용구

  • 예외 방지
  • 기본값 제공
  • 비용이 많이 드는 작업 건너뛰기
a = 0
b = 1

a != 0 and (b / a) > 0
False
def is_divisible(a, b):
    return b != 0 and a % b == 0

단락 평가의 또 다른 흥미로운 사용 사례는 복합 논리식을 생성하면서 비용이 많이 드는 작업을 피하는 것입니다. 예를 들어, 특정 조건이 false인 경우에만 실행해야 하는 비용이 많이 드는 작업이 있는 경우 다음 스니펫과 같이 or을 사용할 수 있습니다. 이 구성에서 clean_data() 함수는 비용이 많이 드는 작업을 나타냅니다. 단락 평가로 인해 이 함수는 data_is_clean가 false인 경우에만 실행됩니다. 이는 데이터가 깨끗하지 않음을 의미합니다.

# data_is_clean or clean_data(data)

이 기술의 또 다른 변형은 주어진 조건이 true인 경우 비용이 많이 드는 작업을 실행하려는 경우입니다. 이 경우 and 연산자를 사용할 수 있습니다.

# data_is_updated and process_data(data)

복합 표현식과 연결된 표현식

number = 5
0 <= number <= 10
True

조건식 또는 삼항 연산자

# variable = expression_1 if condition else expression_2

이 표현식은 조건이 true이면 expression_1을 반환하고 그렇지 않으면 expression_2를 반환합니다. 이 표현식은 다음과 같은 일반 조건문과 동일합니다.

#if condition:
#    variable = expression_1
#else:
#    variable = expression_2

Python의 항등 연산자 및 표현식

x = 1001
y = 1001

print(x == y)

print(x is y)
True
False

이 예에서 x 및 y는 값이 1001인 개체를 나타냅니다. 그래서 그들은 동등합니다. 그러나 동일한 개체를 참조하지 않습니다. 이것이 is 연산자가 False를 반환하는 이유입니다. 내장된 id() 함수를 사용하여 객체의 ID를 확인할 수 있습니다.

print(id(x))
print(id(y))
139928939766288
139928939766224
a = "Hello, Pythonista!"
b = a

print(id(a))
print(id(b))
      
print(a is b)
139928941588320
139928941588320
True
x = 1001
y = 1001
x is not y
True
a = "Hello, Pythonista!"
b = a
a is not b
False

Python의 멤버쉽 연산자 및 표현식

멤버십 테스트는 프로그래밍에 있어 매우 일반적이고 유용합니다. 다른 많은 일반적인 작업과 마찬가지로 Python에는 멤버십 테스트를 위한 전용 연산자가 있습니다. Python in 및 not in 연산자는 바이너리입니다. 이는 두 개의 피연산자를 두 연산자 중 하나로 연결하여 멤버십 표현식을 만들 수 있음을 의미합니다. 그러나 멤버십 표현식의 피연산자에는 다음과 같은 특별한 특성이 있습니다.

  • 왼쪽 피연산자: 값 모음에서 찾으려는 값
  • 오른쪽 피연산자: 대상 값을 찾을 수 있는 값 모음
print(5 in [2, 3, 5, 9, 7])

print(8 in [2, 3, 5, 9, 7])
True
False
print(5 not in [2, 3, 5, 9, 7])

print(8 not in [2, 3, 5, 9, 7])
False
True

연결 및 반복 연산자와 표현식

  • 연산자가 연결 연산자를 정의하고 * 연산자는 반복 연산자를 나타냅니다. 두 연산자 모두 이진수입니다. 연결 연산자는 두 시퀀스를 피연산자로 사용하고 동일한 유형의 새 시퀀스를 반환합니다. 반복 연산자는 시퀀스와 정수를 피연산자로 사용합니다. 일반 곱셈과 마찬가지로 피연산자의 순서는 반복 결과를 변경하지 않습니다.
print("Hello, " + "World!")

print(("A", "B", "C") + ("D", "E", "F"))

print([0, 1, 2, 3] + [4, 5, 6])
Hello, World!
('A', 'B', 'C', 'D', 'E', 'F')
[0, 1, 2, 3, 4, 5, 6]
print("Hello" * 3)

print(3 * "World!")

print(("A", "B", "C") * 3)

print(3 * [1, 2, 3])
HelloHelloHello
World!World!World!
('A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C')
[1, 2, 3, 1, 2, 3, 1, 2, 3]

Walrus 연산자 및 할당 표현식

= 연산자가 포함된 일반 할당문에는 이미 배웠듯이 반환 값이 없습니다. 대신 할당 연산자는 변수를 생성하거나 업데이트합니다. 따라서 연산자는 표현식의 일부가 될 수 없습니다.

Python 3.8부터 새로운 유형의 할당을 허용하는 새로운 연산자에 액세스할 수 있습니다. 이 새로운 할당을 할당 표현식 또는 명명된 표현식이라고 합니다. 새로운 연산자는 바다코끼리 연산자라고 하며 콜론과 등호(:=)의 조합입니다.

일반 할당과 달리 할당 표현식에는 반환 값이 있으므로 표현식입니다. 따라서 프로그래머는 두 가지 작업을 수행합니다.

  • 표현식의 결과를 반환합니다.
  • 결과를 변수에 할당합니다.

바다코끼리 연산자는 이항 연산자이기도 합니다. 왼쪽 피연산자는 변수 이름이어야 하며 오른쪽 피연산자는 Python 표현식일 수 있습니다. 연산자는 표현식을 평가하고 해당 값을 대상 변수에 할당한 다음 값을 반환합니다.

def validate_length(string):
    if (n := len(string)) < 8:
        print(f"Length {n} is too short, needs at least 8")
    else:
        print(f"Length {n} is okay!")

validate_length("Pythonista")
validate_length("Python")
Length 10 is okay!
Length 6 is too short, needs at least 8

Python의 비트 연산자 및 표현식

# Bitwise AND
#   0b1100    12
# & 0b1010    10
# --------
# = 0b1000     8
print(bin(0b1100 & 0b1010))

print(12 & 10)
0b1000
8
# Bitwise AND
#   0b1100    12
# & 0b1010    10
# --------
# = 0b1110    14
print(bin(0b1100 | 0b1010))

print(12 | 10)
0b1110
14

Python의 연산자 우선 순위

연산자설명

** 지수화
+x, -x, ~x 단항 긍정, 단항 부정, 비트 부정
*, /, //, % 곱셈, 나눗셈, 바닥 나눗셈, 모듈로
+, - 덧셈, 뺄셈
<<, >> 비트 단위 시프트
& 비트별 AND
^ 비트열 XOR
| 비트열 OR
==, ~=, <, <=, >, >+, is, is not, in , not in 비교, 정체성, 멤버십
not 부울 NOT
and 부울 AND
or 부울 OR
:= walrus

출처 : https://realpython.com/python-operators-expressions/