Python 프로그래밍 필수 개념

이번 포스팅에서는 Python을 처음 배우기 시작했을 때, 주의를 기울이지 않았거나 간과했던 Python 프로그래밍 필수 개념 학습을 위한 내용을 정리해서 설명해 드리겠습니다.

Python 프로그래밍 언어는 단순성과 가독성으로 높이 평가되며 다양하고 강력한 기능과 개념을 제공합니다. Python를 배우면서 프로그래밍 효율성과 효율성을 크게 향상 시킬 수 있는 필수 개념이 있습니다.

여러분들도 이러한 기본 개념부터 고급 개념까지 학습하여 해당 개념의 중요성과 구현 방법을 잘 이해할 수 있으면 좋겠습니다.

Python 프로그래밍 필수 개념


한 줄에 변수 할당

한 줄에 변수를 할당한다는 것은 단일 코드 줄에 있는 여러 변수에 값을 할당한다는 의미입니다. 이는 코드의 간결성과 명확성을 위해 수행되는 경우가 많습니다.

x, y, z = 1, 2, 3

한 줄에 세 개의 변수 x, y 및 z를 각각의 값 1, 2 및 3으로 초기화했습니다. 이는 한 번에 여러 변수에 값을 할당하는 간결한 방법입니다.


리스트/튜플 언패킹(Unpacking)

리스트 또는 튜플 언패킹(Unpacking)의 압축을 푸는 것은 해당 요소를 추출하여 개별 변수에 할당하는 것을 의미합니다.
이는 데이터 구조에 포함된 개별 값으로 작업하는 편리한 방법입니다.

다음은 여러 값을 포함하는 목록 또는 튜플입니다.

my_tuple = (1, 2, 3)

이 값을 다음과 같은 별도의 변수로 압축을 풀 수 있습니다.

a, b, c = my_tuple

이제 a는 값 1을 갖고, b는 값 2를 가지며, c는 값 3을 갖습니다.

이는 인덱스를 사용하여 액세스할 필요 없이 리스트나 튜플의 요소를 개별적으로 작업하려는 경우에 유용합니다.
언팩킹(Unpacking)은 여러 값을 튜플로 반환한 다음 함수를 호출할 때 압축을 풀기 위해 함수에서 일반적으로 사용됩니다.


문자열 형식화(String Formatting)

문자열 형식을 사용하면 제어된 방식으로 문자열에 값을 삽입할 수 있습니다. 이는 출력 텍스트의 모양과 구조를 제어하는 데 도움이 됩니다. Python에는 % 연산자와 str.format() 메서드를 포함하여 문자열 형식을 지정하는 다양한 방법이 있습니다.

다음은 Python에서 문자열 형식을 지정하는 간결한 방법인 f-문자열을 사용하는 예입니다.

name = "철수"
age = 27
formattedString = f"My name is {name} and I am {age} years old."
print(formattedString)
---------------------------------------------------------------------
My name is 철수 and I am 27 years old.

이 경우 f-문자열  f”My name is {name} and I am {age} years old.” name 및 age 값을 문자열에 동적으로 삽입합니다.


True / False Value

Python의 True 값과 False 값은 if 문이나 부울 컨텍스트와 같은 조건식에서 값이 해석되는 방식을 나타냅니다. Python에서 특정 값은 “truthy”로 간주됩니다.

즉, 부울 컨텍스트에서 평가할 때 True로 처리되는 반면, 다른 값은 “falsey”로 간주됩니다. 즉 False로 처리됩니다.

Python의 True 값에는 0이 아닌 숫자, 비어 있지 않은 문자열, 비어 있지 않은 리스트, 비어 있지 않은 딕셔너리 및 객체를 포함합니다. 아래 예에서 if 문은 5를 실제 값으로 평가하므로 if 블록 내부의 코드가 실행됩니다.

if 5: 
    print("This will be printed") 
-------------------------------------
This will be printed

Python의 False 값에는 0, None, 빈 문자열 “ ”, 빈 리스트 [] 및 빈 딕셔너리 { }를 포함합니다. 아래 예에서 if 문은 0을 False 값으로 평가하므로 if 블록 내부의 코드는 실행되지 않습니다.

if 0: 
    print("This won't be printed")


Ternary Operator(삼항연산자)

조건식이라고도 하는 삼항 연산자를 사용하면 한 줄에 간결한 조건문을 작성할 수 있습니다. 조건에 따라 변수에 값을 할당할 수 있습니다.

x = 10 
result = "Even" if x % 2 == 0 else "Odd"
result
---------------------------------------------
'Even'

이는 x가 짝수이면 변수 결과에 Even 값을 할당하고 그렇지 않으면 Odd 값을 할당합니다.


Short Circuiting(단락)

Short Circuiting(단락)은 논리 연산자의 동작(예: and 또는 결과가 첫 번째 피연산자에 의해 결정될 수 있는 경우 두 번째 피연산자가 평가되지 않음)을 나타냅니다.

이러한 최적화를 통해 코드 효율성을 향상하고 불필요한 계산을 방지할 수 있습니다.

a = 10
b = 5

if b > 5 and a / b > 2:
    print("두 가지 조건 모두 참.")
else:
    print("첫 번째 조건이 거짓이기 때문에 단락됨(Short-circuited)")
--------------------------------------------------------------------
첫 번째 조건이 거짓이기 때문에 단락됨(Short-circuited)

변수 b가 5보다 크지 않기 때문에 두 번째 조건 a/b > 2는 평가되지 않으므로 “첫 번째 조건이 거짓이기 때문에 단락됨(Short-circuited)” 가 출력됩니다.


Mutable vs. Immutable Types(변경 가능 유형과 불변 유형)

Python에서 데이터 유형은 생성된 후 해당 값의 변경 여부에 따라 Mutable(변경 가능) 또는 Immutable(불변)으로 분류될 수 있습니다.변경 가능한 데이터 유형은 값이 생성된 후 수정하거나 변경할 수 있는 유형입니다.

리스트, 딕셔너리 및 세트는 변경 가능한 데이터 유형의 예입니다. 변경 가능한 객체를 수정하면 ID(메모리 주소)는 유지되지만 내용은 변경될 수 있습니다.

myList = [1, 2, 3]
myList.append(4)  
print(myList)
---------------------
[1, 2, 3, 4]

반면, 불변 데이터 유형은 일단 생성되면 변경할 수 없습니다. 불변 데이터 유형의 예로는 문자열, 튜플, 고정 세트 등이 있습니다. 불변 객체를 수정하는 것처럼 보이는 모든 작업은 실제로 수정된 값을 가진 새 객체를 생성합니다.

여기서는 문자열을 사용한 불변성을 보여줍니다.

name = "Ifeanyi"
name += " Otuonye"
print(name)
-----------------------
Ifeanyi Otuonye

name 변수에 “Otuonye”를 추가하더라도 원래 문자열을 수정하지 않고 새 문자열을 생성하여 문자열의 불변성을 보여줍니다.


List Comprehension

List Comprehension는 리스트를 만드는 간결한 방법입니다. 기존 반복 가능 항목(예: 리스트, 튜플 또는 범위)의 각 항목에 연산이나 표현식을 적용하여 새 리스트를 생성할 수 있습니다.

originalNumbers = [1, 2, 3, 4, 5, 6]
squaresOfEvens = [x ** 2 for x in originalNumbers if x % 2 == 0]
squaresOfEvens
---------------------------------------------------------------------
[4, 16, 36]

위 코드는 숫자 리스트를 사용하여 원래 리스트에서 짝수의 제곱만 포함하는 새 리스트를 만드는 코드입니다. squaresOfEvens 리스트를 생성하고 x ** 2 표현식을 originalNumbers 리스트의 각 요소 x에 적용합니다. 단, x % 2 == 0 조건이 충족되는 경우에만 적용됩니다.

결과적으로 squaresOfEvens에는 원래 리스트에 있는 짝수의 제곱인 [4, 16, 36]이 포함됩니다.


딕셔너리 기본값

딕셔너리는 key-value 쌍의 모음입니다. 딕셔너리의 값에 액세스하려는 경우 .get() 메서드를 사용하여 지정된 key와 연결된 value를 검색할 수 있습니다. key가 있으면 해당 value를 반환하지만, key가 없으면 기본 대체 값을 제공할 수 있습니다.

# 딕셔너리 생성
userData = {
  "name": "John", 
  "age": 30
}

# .get() 메소드와 기본값을 가지는 value에 접근하기 
occupation = userData.get("occupation", "unknown")

print(f"The occupation is {occupation}.")
-----------------------------------------------------------
The occupation is unknown.

여기서 .get() 메소드는 userData 딕셔너리에서 “occupation” key와 연관된 value를 검색하려고 시도하지만 key가 존재하지 않고 기본값(“unknown”)을 출력합니다.


Enumerate()

enumerate()는 반복 가능한 객체의 인덱스와 값을 모두 반복하는 데 사용되는 내장 함수입니다.

fruits = ['사과', '바나나', '체리']
for index, fruit in enumerate(fruits, start = 1):
    print(f"Item {index}: {fruit}")
--------------------------------------------------------
Item 1: 사과
Item 2: 바나나
Item 3: 체리

enumerate(fruits, start=1) 은 fruits 리스트를 반복하면서 (인덱스, fruits) 쌍을 생성하는 반복자를 생성합니다. start = 1 매개변수는 초기 인덱스를 기본값 0 대신 1로 설정합니다.


Sets and Frozensets(집합과 고정집합)

Sets and Frozensets(집합과 고정집합)은 고유한 값 모음을 저장하는 데 사용되는 Python의 데이터 구조입니다. 이들 간의 주요 차이점은 집합은 변경 가능(수정 가능)하고, 고정집합은 불변(생성 후 수정할 수 없음)이라는 것입니다.

여기서는 고유 번호를 저장하는 세트를 만듭니다.

# 집합 생성
fruits = {"사과", "바나나", "체리", "바나나"}

# 요소 추가
fruits.add("오렌지")

# 요소 제거
fruits.remove("체리")

print(fruits)
-------------------------------------------------
{'사과', '바나나', '오렌지'}

fruits 집합은 고유한 요소를 저장하고 출력 결과에서 중복된 값을 자동으로 제거합니다.

여기에서는 고유한 숫자를 저장하도록 정의된 Frozenset() 생성자를 만듭니다.

# 고정집합 생성
colors = frozenset(["빨강", "녹색", "파랑"])

colors.add("yellow") # 실행 시 아래와 같은 에러 문구가 발생함
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[15], line 4
      1 # 고정집합 생성
      2 colors = frozenset(["빨강", "녹색", "파랑"])
----> 4 colors.add("yellow")

AttributeError: 'frozenset' object has no attribute 'add'
print(colors)
------------------------------------------
frozenset({'red', 'green', 'blue'})


*Args and **Kwargs

이는 가변 개수의 인수 및 키워드 인수를 사용하기 위해 함수 정의에 사용되는 특수 구문입니다.

*args는 키워드가 아닌(위치) 인수의 가변 개수를 함수에 전달하는 데 사용됩니다. 이를 통해 원하는 수의 인수를 전달할 수 있으며 함수 내부의 튜플로 수집됩니다.

**kwargs를 사용하면 가변 개수의 키워드 인수를 허용할 수 있습니다.

def example_function(arg1, *args, kwarg1 = "default", **kwargs): 
    print("arg1:", arg1) 
    print("args:", args) 
    print("kwarg1:", kwarg1) 
    print("kwargs:", kwargs) 

example_function(1, 2, 3, kwarg1 = "custom", option1 = "A", option2 = "B")
--------------------------------------------------------------------------------
arg1: 1
args: (2, 3)
kwarg1: custom
kwargs: {'option1': 'A', 'option2': 'B'}
  • arg1은 첫 번째 위치 인수 1을 받습니다.
  • *args는 arg1 이후의 추가 위치 인수를 튜플로 수집합니다. 이 경우 args 튜플에 2와 3을 수집합니다.
  • kwarg1은 키워드 인수 kwarg1 = “custom”을 받습니다.
  • **kwargs는 함수 서명에 명시적으로 명명되지 않은 추가 키워드 인수를 사전에 수집합니다. 이 경우 option1 = “A” 및 option2 = “B”를 kwargs 딕셔너리에 수집합니다.


Docstrings

Docstring은 함수, 클래스 또는 모듈에 대한 문서를 제공하는 데 사용되는 여러 줄의 문자열 리터럴입니다. 개발자가 코드를 사용하고 작업하는 방법을 이해하는 데 도움이 됩니다.

def greet(name): 
    """ 매개변수로 전달받은 사람에게 인사하는 함수입니다. """
    print(f"Hello, {name}!") 

# docstring 접근
docstring = greet.__doc__
print(docstring)
-------------------------------------------------------------
매개변수로 전달받은 사람에게 인사하는 함수입니다. 

Docstring greet 함수의 목적과 사용법에 대한 정보를 제공합니다. .__doc__ 속성을 사용하여 함수, 클래스 또는 모듈의 Docstring에 접근할 수도 있습니다.

이 코드를 실행하면 Greeting 함수의 독스트링이 출력됩니다.


예외 처리

예외 처리는 프로그램 실행 중에 발생할 수 있는 예외 상황이나 오류를 예상하고 처리할 수 있도록 오류를 적절하게 관리하는 데 중요합니다. 이를 통해 오류가 발생할 때 정보 오류 메시지 제공, 문제 기록, 코드에서 대체 경로 선택 등 특정 조치를 취할 수 있습니다.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("0으로 나누는 것은 허용되지 않습니다.")
-------------------------------------------------
0으로 나누는 것은 허용되지 않습니다.

이 코드는 0으로 나누는 오류를 처리하고 사용자에게 친숙한 메시지를 표시하여 프로그램 충돌을 방지합니다.


Walrus Operator (:=)

Python 3.8에 도입된 Walrus Operator는 표현식의 일부로 변수에 값을 할당합니다.

while (user_input := input("Enter 'quit' to exit: ")) != 'quit': 
    print(f"You entered: {user_input}")

# ok 입력 시 출력 예시
------------------------------------------------------------------------
Enter 'quit' to exit: ok
You entered: ok

여기에서는 사용자가 입력한 값을 user_input에 넣고 한 줄에서 입력값이 ‘quit’와 같은지 확인합니다.


Generators

Generators를 사용하면 Yield 키워드로 함수를 정의하여 반복 가능한 값 시퀀스를 효율적으로 생성할 수 있습니다. 필요에 따라 즉시 값을 생성하므로 메모리를 절약하는 데 도움이 됩니다.

Generators 함수는 일반 함수처럼 정의되지만 하나 이상의 yield 문을 포함합니다. yield가 포함된 함수가 호출되면 전체 함수를 한 번에 실행하는 것이 아니라 반복하여 한 번에 하나씩 값을 생성할 수 있는 Generators 개체를 반환합니다.

다음은 짝수를 생성하는 생성기를 정의합니다.

def count_up_to(n):
    i = 1
    while i <= n:
        yield i
        i += 1

# generator 객체 생성
counter = count_up_to(5)

# 한번에 하나의 값을 가지는 generator 반복
for num in counter:
    print(num)
----------------------------------------------------
1
2
3
4
5

count_up_to 함수는 1부터 n까지의 값을 생성하는 생성기입니다. 생성기 개체 counter를 생성하면 함수가 즉시 실행되지 않습니다. 대신 반복자를 생성합니다.

counter를 반복하면 반복하면서 한 번에 하나씩 값이 생성됩니다. 이는 모든 값의 리스트를 미리 생성하는 것보다 메모리를 효율적으로 사용할 수 있입니다.


Lambda 함수

Python의 Lambda 함수는 공식적인 def 문 없이도 작은 익명 함수를 생성할 수 있는 간결한 인라인 함수입니다. 간단한 함수가 필요하고 별도로 명명된 함수를 정의하고 싶지 않을 때 특히 유용합니다.

Lambda 함수는 map, filter, sort와 같은 고차 함수와 함께 사용하는 경우가 많습니다. 여기서 Lambda 함수는 map과 함께 사용되어 숫자 리스트를 제곱합니다.

numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)
-------------------------------------------------
[1, 4, 9, 16, 25]

여기서는 Lambda 함수(lambda x: x**2)가 숫자 리스트의 각 요소에 적용되어 제곱 숫자 리스트를 생성합니다.


컨텍스트 관리자

컨텍스트 관리자는 파일 자동 닫기, 잠금 해제, 더 이상 필요하지 않은 리소스 정리 등 적절한 리소스 관리를 보장하는 데 사용됩니다. 리소스 처리를 단순화하고 코드 가독성을 높이는 데 도움이 됩니다.

# 콘텍스트 관리자를 사용해서 파일을 열고 닫기
with open('test.txt', 'w') as file:
    file.write('Hello, World!')

이 경우 with 문 내부의 블록이 종료되면 파일이 자동으로 닫혀 리소스를 올바르게 관리할 수 있습니다.


모듈

Python을 사용하면 더 나은 구성, 재사용성 및 유지 관리성을 위해 코드를 모듈로 구성할 수 있습니다. 모듈은 다른 Python 스크립트로 가져올 수 있는 함수, 변수 및 클래스가 포함된 단일 Python 파일입니다. 관련 코드를 캡슐화하고 코드 재사용성을 높이는 데 사용됩니다.

여기에 math_Operations.py라는 파일이 있습니다.

# math_operations.py

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

이 모듈을 다른 Python 스크립트로 가져와 사용할 수 있습니다.

# main.py

import math_operations

result = math_operations.add(5, 3)
print(result)
-----------------------------------------
8


Decorators

Decorators(데코레이터)는 다른 함수나 메서드의 동작을 수정하거나 향상시키는 함수입니다. 소스 코드를 변경하지 않고 함수나 메소드에 함수를 추가하는 데 사용되며 일반적으로 로깅, 인증, 액세스 제어 등과 같은 작업에 사용됩니다.

아래 코드에서는 함수의 실행 시간을 측정하기 위해 타이밍 데코레이터가 생성됩니다.

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Execution time: {end_time - start_time} seconds")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)

slow_function()
-------------------------------------------------------------------------
Execution time: 2.0011305809020996 seconds


결론

이번 포스팅에서는 Python 프로그래밍 언어에 이제 막 익숙해진 사람들을 위해 프로그래밍 기술을 크게 향상시킬 수 있는 Python 프로그래밍 필수 개념을 살펴보았습니다.

개인적인 경험을 바탕으로 한 이러한 지식을 통해 여러분이 더 복잡한 코딩 문제를 해결하고 자신감을 갖고 보다 효율적인 Python 코드를 작성할 수 있기를 바랍니다.

감사합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다