Python Basic

EHminShoov2J·2023년 11월 10일
1
post-thumbnail

Python


그동안 파이썬을 쓰면서도 자세하게 알지 못했던 부분을 정리하고자 한다.

1. Sequence Type

리스트, 튜플, 문자열등과 같이 값이 연속적으로 이어진 자료형을 Sequence Type이라고 하며 다음과 같은 공통 method를 사용할 수 있다.

  • 인덱싱
  • 복제 ([1,2,3] * 3)
  • 덧셈 ([1,2,3] + [4,5,6])
  • in (특정 원소가 해당 자료형 안에 존재하는지 확인)
  • 이터레이션 (for loop)
  • enumerate()
  • zip()

Sequence vs Iterable

Iterable이 조금 더 큰 개념이다. indexing을 통해 개별 원소에 접근이 가능하다면 Sequence type이다!

2. Shallow copy 와 Deep copy

mutable 과 immutable


Mutable : 생성된 후에도 변경이 가능한 객체. 대표적으로 list, dict, set등이 있다.
Immutable : 생성이후에 변경이 불가능한 객체로 수정하기 위해서는 새로운 객체를 생성(메모리 할당)해야 한다. 대표적으로 int, str, tuple 등이 있다.

# mutable
my_list = [1, 2, 3]
my_list[0] = 99  # 기존 객체를 직접 수정 가능
#immutable
a = 5
a = a + 1  # 이때 새로운 객체가 생성되어 할당됨

Shallow copy 와 Deep copy

Deep copy : 원본 객체와 복사된 객체가 서로 독립적인 객체를 참조
Shallow copy : 복사된 객체와 원본 객체가 동일한 객체를 참조
이때 immutable 객체에 대해서는 Deep copy가 발생하지만, mutable 객체에 대해서는 Shallow copy가 발생한다. 이때문에 아래와 같이 복사한 객체의 값을 바꾸면 원본 객체의 값도 변하는 문제가 발생한다.

import copy
original_list = [1, [2, 3], 4]
shallow_copied_list = copy.copy(original_list)
# 얕은 복사이므로 내부 리스트는 동일한 객체를 참조
print(original_list)            # [1, [2, 3], 4]
print(shallow_copied_list)      # [1, [2, 3], 4]
# 내부 리스트의 값을 변경하면 원본과 복사된 리스트에 모두 반영
shallow_copied_list[1][0] = 99
print(original_list)            # [1, [99, 3], 4]
print(shallow_copied_list)      # [1, [99, 3], 4]

이런 문제를 해결하기 위해 copy 모듈의 deepcopy() method를 활용하여 해결 가능하다.

import copy
original_list = [1, [2, 3], 4]
deep_copied_list = copy.deepcopy(original_list)
# 깊은 복사이므로 내부 리스트도 새로운 객체를 참조
print(original_list)          # [1, [2, 3], 4]
print(deep_copied_list)        # [1, [2, 3], 4]
# 내부 리스트의 값을 변경해도 원본에만 영향을 줌
deep_copied_list[1][0] = 99
print(original_list)          # [1, [2, 3], 4]
print(deep_copied_list)        # [1, [99, 3], 4]

3.interning

-5 ~ 256까지의 작은 정수를 메모리에 미리 할당하고, 동일한 값의 작은 정수가 생성될 때 마다 미리 할당된 메모리 주소를 참조하게끔 함.

a = 10
b = 10
print(a is b)  # True, 동일한 메모리 주소를 가리킴
c = 257
d = 257
print(c is d)  # False, 서로 다른 메모리 주소를 가리킴

4.String

1) f-string


파이썬 3.6 버전부터 도입된 문자열 포매팅 방법 중 하나로, 문자열 안에 변수나 표현식을 간편하게 삽입할 수 있도록 하는 기능

# 변수값 직접 사용 
name = "Alice"
age = 25
message = f"안녕하세요, {name}님! {age}살이시네요."
# 소수점 이하 자릿수 지정
height = 175.5
message = f"키: {height:.2f}cm"
# 정렬 및 폭 지정
name = "Bob"
age = 30
height = 175.5
message = f"Name: {name:<10}, Age: {age:03d}, Height: {height:.2f}"
# 왼쪽 정렬, 총 10자리, 정수는 3자리, 소수는 2자리까지
# 빈칸 *지정, 가운데 정렬
x = 42
formatted_x = f"The answer is: {x:*^20}"

2) raw string


특수 문자(이스케이프 문자)를 해석하지 않고 그대로 텍스트로 처리

normal_string = "This is a normal string.\nThis is a new line."
print(normal_string)
# 출력:
# This is a normal string.
# This is a new line.
raw_string = r"This is a raw string.\nThis is not a new line."
print(raw_string)
# 출력:
# This is a raw string.\nThis is not a new line.

3) function type hints


함수의 매개변수와 반환 값에 대한 타입 정보를 제공하는 기능이다. Docstring으로 함수에 대한 설명, 변수 설명등을 적어 다른 개발자가 함수를 이해할 수 있도록 하는 것이 좋다.

def add_numbers(x: int, y: int) -> int:
    """
    두 정수를 더하는 함수
    Parameters:
    - x (int): 첫 번째 정수
    - y (int): 두 번째 정수
    Returns:
    int: 두 정수의 합
    """
    return x + y
# 사용 예시
result = add_numbers(5, 10)
print(result)  # 출력: 15
# 타입 오류 발생 예시
# result = add_numbers("5", "10")  # 문자열을 전달하면 타입 오류 발생

5. Pythonic Code

1. join

문자열을 '+'를 통해서 결합하는 경우 새로운 객체가 매번 생성되기 때문에 메모리를 많이 차지하게 된다. 'join' method를 사용하는 경우 보다 효율적인 처리가 가능해짐

# Using join
result = ''.join(str(i) for i in range(10000))

2. list comprehension

보다 간결하게 list를 만들어내는 기법. 미세하게 속도가 빠름!

result = [x if x % 2 == 0 else x**2 for x in range(10)]

3. enumerate

iterable 객체를 입력받아 인덱스와 값을 포함하는 enumerate객체를 returen 해준다.

fruits = ['apple', 'banana', 'cherry']
for index, value in enumerate(fruits):
    print(f"Index: {index}, Value: {value}")
#Index: 0, Value: apple
#Index: 1, Value: banana
#Index: 2, Value: cherry

4. zip

두개 이상의 iterable을 묶어주는 역할

5. map

주어진 함수를 지정된 iterable의 모든 요소에 적용하여 새로운 map 객체를 생성한다. (iterator란 iterable에서 값을 하나씩 가져오는 객체로, map을 사용해서 객체를 생성하는경우 사용시점에 값을 생성하기 때문에 메모리 효율적이다)

6. generator

yield 키워드를 활용하여 메모리에 저장하지 않는 특별한 종류의 iterator를 생성.
yield를 사용하여 값을 생성하고, 일시 중단.

def even_numbers_generator(limit):
    number = 0
    while number < limit:
        yield number
        number += 2
# 제너레이터 객체 생성
even_gen = even_numbers_generator(10)
# 제너레이터를 사용하여 값 순회
for num in even_gen:
    print(num)

데이터가 커져도 다룰수 있다는 장점을 가지고 있음

7. keyword arguments

함수 호출 시 인자를 전달할 때, 각 인자의 이름을 명시적으로 지정하여 값을 전달하는 방식

8. asterisk

단순 곱셈, 제곱 연산, 가변인자 활용, unpacking 까지 다양하게 사용

  • unpacking : iterable(순회 가능한) 객체에서 요소를 개별 변수로 추출
def add_numbers(a, b, c):
    return a + b + c
numbers = [1, 2, 3]
# Unpacking 함수 인자
result = add_numbers(*numbers)
print("Result:", result)

6.OOP

  • OOP는 클래스와 실제 구현인 Instance로 구성된다.
  • Inheritance : 클래스 간에 코드를 재사용하는 메커니즘을 제공
  • Polymorphism : 동일한 인터페이스를 사용하여 여러 객체 타입을 처리할 수 있는 능력으로 주로 메서드 오버라이딩과 관련
  • Visibility : 객체의 속성이나 메서드에 대한 접근 권한을 제어하는 것
    • public: 어떠한 제한도 없음.
    • _protected: 클래스 자체 및 해당 클래스를 상속받은 클래스에서 접근 가능.
    • __private: 해당 클래스에서만 접근 가능.
  • Decorate : 함수를 받아 일부 작업을 수행한 후 해당 함수를 반환하는 함수
def trace(func):                             # 호출할 함수를 매개변수로 받음
    def wrapper():
        print(func.__name__, '함수 시작')    # __name__으로 함수 이름 출력
        func()                               # 매개변수로 받은 함수를 호출
        print(func.__name__, '함수 끝')
    return wrapper                           # wrapper 함수 반환
@trace    # @데코레이터
def hello():
    print('hello')
@trace    # @데코레이터
def world():
    print('world')
hello()    # 함수를 그대로 호출
world()    # 함수를 그대로 호출

7.정규식

문자열의 검색, 매칭, 교체 등의 작업을 수행하는데 사용되는 강력한 도구

  • 문자 클래스 ([ ]): 괄호 안에 들어가는 문자 중 하나와 매치.
  • 마침표(.): 어떤 한 문자와 매치됩니다. 단, 새 줄 문자(\n)는 제외됩니다.
  • 반복 (*, +, ?):
    • *: 0번 이상 반복
    • +: 1번 이상 반복
    • ?: 0번 또는 1번 반복
  • 메타문자(^, $):
    • ^: 문자열의 시작과 매치
    • $: 문자열의 끝과 매치

8. JSON

9. Pandas

10. Numpy

0개의 댓글