[파이썬 코딩의 기술] - 2장 리스트와 딕셔너리

2025. 2. 14. 21:33·리뷰/책

2장 리스트와 딕셔너리

  • 딕셔너리(Dictionary)는 검색에 사용할 키(key)와 키에 연관된 값(value)을 저장하는 구조이다.
  • 내부적으로 해시 테이블(Hash Table)을 사용하며, 평균적으로 O(1)의 시간 복잡도로 원소를 삽입 및 검색할 수 있다.
  • 동적인 데이터를 관리할 때 가장 이상적인 자료구조이다.

2-11 시퀀스를 슬라이싱하는 방법을 익혀라

  • 슬라이싱(Slicing)을 사용하면 리스트 등의 시퀀스를 특정 부분만 잘라서 쉽게 접근할 수 있다.
  • 슬라이싱을 할 때 가독성을 높이는 규칙:
    • 리스트의 맨 앞부터 슬라이싱할 때 0을 생략해야 한다. (예: a[:5])
    • 리스트의 끝까지 슬라이싱할 때 끝 인덱스를 생략해야 한다. (예: a[5:])
  • 슬라이싱 결과는 완전히 새로운 리스트이며, 원래 리스트에 영향을 주지 않는다.

기억해야 할 내용:

  • 슬라이싱은 간결하게 작성하라. 시작 인덱스에 0을 넣거나 끝 인덱스에 리스트 길이를 넣지 않는다.
  • 범위를 초과하는 인덱스를 허용한다. 예를 들어 a[:20]이나 a[-20:]과 같이 범위를 벗어난 값도 사용할 수 있다.
  • 리스트 슬라이스에 대입하면 원래 시퀀스의 부분을 변경할 수 있다.
    • 슬라이스한 부분과 대치할 시퀀스의 길이가 다르더라도 적용 가능하다.

찾아봐야하는 내용.




2-12 스트라이드와 슬라이스를 한 식에 함께 사용하지 말라

  • 스트라이드(Stride)는 [start:end:stride] 형태로 증가값을 포함하는 슬라이싱 방법이다.
  • 스트라이드를 사용할 경우 예기치 못한 동작이 발생할 수 있어 주의해야 한다.
  • 예를 들어, 문자열을 뒤집을 때는 [::-1]을 사용한다.
x = b'mongoose'
y = x[::-1]
print(y)
# 출력: b'esognom'
  • 유니코드 문자열과 UTF-8로 인코딩된 바이트 문자열은 동작 방식이 다르므로 주의해야 한다.

기억해야 할 내용:

  • 슬라이스에 시작, 끝, 증가값을 함께 지정하면 코드의 의미가 혼동될 수 있다.
  • 양수 증가값을 사용하라. 가능하면 음수 증가값은 피하라.
  • 한 슬라이스에서 시작, 끝, 증가값을 함께 사용하지 말라.
    • 대안 1: 두 번의 대입을 사용하여 한 번은 스트라이딩, 한 번은 슬라이싱을 수행하라.
    • 대안 2: itertools.islice()를 사용하여 더 명확한 코드로 작성하라.



2-13 슬라이싱보다는 나머지를 모두 잡아내는 언패킹을 사용하라

  • 기본 언패킹의 한계

    • 언패킹할 시퀀스의 길이를 미리 알고 있어야 한다.

    • 여러 개의 변수를 인덱싱과 슬라이싱을 통해 할당하면 실수할 가능성이 높다.

      oldest = car_ages_descending[0]
      second_oldest = car_ages_descending[1]
      others = car_ages_descending[2:]
      print(oldest, second_oldest, others)
      
    • 위 코드에서 인덱스 조정을 깜빡하면 잘못된 결과가 나올 수 있다.

  • 해결 방법: `` * (별표) 기호를 사용한 언패킹

      oldest, second_oldest, *others = car_ages_descending
      print(oldest, second_oldest, others)
    
    • others는 나머지 모든 요소를 리스트로 저장한다.
    • 실수를 줄이고 코드 가독성을 높일 수 있다.

별표(*``) 언패킹의 특징

  • 언패킹할 변수 중 하나 이상은 필수

      • 하나만 사용하면 SyntaxError 발생

      ```python

    • others = car_ages_descending # SyntaxError 발생

  • 한 수준의 언패킹에서 *은 하나만 사용 가능

      first, *middle, *last = car_ages_descending  # SyntaxError 발생
    

기억해야 할 내용

  • 언패킹 대입에 별표 식을 사용하면 언패킹 패턴에서 대입되지 않는 모든 부분을 리스트에 잡아낼 수 있다.
  • 별표 식은 언패킹 패턴의 어떤 위치에든 놓을 수 있다. 별표 식에 대입된 결과는 항상 리스트가 되며, 이 리스트에는 별표 식이 받은 값이 0개 또는 그 이상 들어간다.
  • 리스트를 서로 겹치지 않게 여러 조각으로 나눌 경우, 슬라이싱과 인덱싱을 사용하기 보다는 나머지를 모두 잡아내는 언패킹을 사용해야 실수할 여지가 훨씬 줄어든다.



2-14 복잡한 기준을 사용해 정렬할 때는 key 파라미터를 사용하라

  • 파이썬의 list 내장 타입에는 리스트 원소를 정렬하는 sort 메서드가 있다.
  • 기본적으로 원소 타입에 맞춰 오름차순 정렬을 수행한다.
  • 사용자가 만든 객체를 정렬하려면 정렬 기준이 될 속성(애트리뷰트)을 key 파라미터로 지정해야 한다.

key 파라미터를 이용한 정렬

names = ['김', '민수', '영희쌤']

# x는 리스트의 각 요소를 의미
# len(x)는 각 요소의 길이를 반환

sorted_names = sorted(names, key=lambda x: len(x))
print(sorted_names)  # 출력: ['김', '민수', '영희쌤']

# 실행 과정:
# 1. x = '김' -> len(x) = 1
# 2. x = '민수' -> len(x) = 2
# 3. x = '영희쌤' -> len(x) = 3
  • key 함수는 정렬 기준이 될 값을 반환하는 함수이다.
  • 위 코드에서는 문자열의 길이를 기준으로 정렬했다.

객체의 특정 속성을 기준으로 정렬

class Car:
    def __init__(self, color, brand):
        self.color = color
        self.brand = brand

my_car = Car("빨강", "현대")  # 객체 생성 예제
  • Car 클래스에는 color와 brand 속성이 존재한다.
  • 정렬 시 특정 속성을 기준으로 정렬할 수 있다.

여러 기준을 활용한 정렬

power_tools.sort(key=lambda x: (x.weight, x.name))
print(power_tools)
# 출력: [Tool('드릴', 4), Tool('연마기', 4), Tool('원형 톱', 5), Tool('착암기', 40)]
  • (x.weight, x.name)을 반환하여 무게(weight)를 기준으로 정렬하고, 동일한 무게일 경우 이름(name)으로 정렬한다.

내림차순 정렬

power_tools.sort(key=lambda x: (x.weight, x.name), reverse=True)
print(power_tools)
# 출력: [Tool('착암기', 40), Tool('원형 톱', 5), Tool('연마기', 4), Tool('드릴', 4)]
  • reverse=True를 설정하면 모든 정렬 기준이 내림차순이 된다.

여러 번 정렬하여 복합 정렬 적용

power_tools.sort(key=lambda x: x.name)  # name 기준 오름차순 정렬
power_tools.sort(key=lambda x: x.weight, reverse=True)  # weight 기준 내림차순 정렬
print(power_tools)
# 출력: [Tool('착암기', 40), Tool('원형 톱', 5), Tool('드릴', 4), Tool('연마기', 4)]
  • 여러 정렬 기준을 적용할 경우 우선순위가 낮은 기준부터 정렬해야 한다.
  • 먼저 name 기준으로 정렬한 후, weight 기준으로 정렬하면 원하는 결과를 얻을 수 있다.

기억해야 할 내용

  • sort 메서드는 기본적으로 문자열, 정수, 튜플 등 자연스러운 순서가 있는 타입을 정렬할 수 있다.
  • 사용자가 만든 객체를 정렬하려면 key 파라미터를 사용해 정렬 기준을 지정해야 한다.
  • 튜플을 반환하는 key 함수를 사용하면 여러 정렬 기준을 한 번에 적용할 수 있다.
  • 정렬 기준이 여러 개일 경우, 낮은 우선순위 기준부터 정렬한 후 높은 우선순위 기준으로 정렬해야 한다.
  • 정렬 방향을 반대로 지정하려면 reverse=True를 사용하거나, 부호를 바꿀 수 있는 값이면 - 연산자를 사용하면 된다.



2-15 딕셔너리 삽입 순서에 의존할 때는 조심하라

  • 파이썬 3.5 이전: 딕셔너리의 삽입 순서가 보장되지 않았다.
  • 파이썬 3.7 이후: 딕셔너리의 삽입 순서가 보장됨. 즉, dict를 이터레이션할 때 삽입한 순서대로 키를 반환한다.
  • 하지만, 모든 딕셔너리와 비슷한 객체가 삽입 순서를 보장한다고 가정하면 안 된다.

딕셔너리 삽입 순서 보장 예제

my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in my_dict:
    print(key)
# 출력: a, b, c  (삽입한 순서대로 출력됨)

딕셔너리와 유사한 객체에서의 주의점

파이썬에서는 dict가 아니지만 딕셔너리처럼 동작하는 클래스를 쉽게 만들 수 있다.

이 경우, 덕 타이핑(Duck Typing)으로 인해 예상치 못한 동작이 발생할 수 있으며, 특히 삽입 순서가 유지되지 않을 수도 있음을 유의해야 한다.

  • 유사 딕셔너리

    유사 딕셔너리란?

    딕셔너리처럼 동작하지만 실제 dict가 아닌 객체를 말한다.

    일반 딕셔너리와 다르게 동작할 수 있어 주의해야 한다.

    예제

    1. defaultdict → 없는 키를 조회하면 기본값을 자동으로 반환

    2. 직접 만든 FakeDict → 내부 동작을 마음대로 변경 가능 (예: 키 순서 변경)

    3. os.environ → 환경 변수를 저장하지만 실제 dict가 아님

    주의할 점

    • 딕셔너리와 다르게 동작할 수 있으므로 조심해야 한다.

    • isinstance(obj, dict)로 실제 딕셔너리인지 확인하는 것이 좋다.

    • 이해하기 쉬운 예제*

      from collections import defaultdict
      
      # 일반 딕셔너리
      normal_dict = {}
      # 없는 키를 조회하면 오류 발생
      # print(normal_dict['a'])  # KeyError
      
      # 유사 딕셔너리 (defaultdict)
      default_dict = defaultdict(int)
      print(default_dict['a'])  # 0 (오류 없이 기본값 반환)

      → 일반 딕셔너리는 없는 키를 조회하면 오류가 나지만, defaultdict는 기본값을 반환한다.

      → 이런 차이 때문에 딕셔너리처럼 보이지만 조심해야 한다.

덕 타이핑으로 인한 오류 예제

class FakeDict:
    def __init__(self):
        self.data = {}

    def __setitem__(self, key, value):
        self.data[key] = value

    def __getitem__(self, key):
        return self.data[key]

    def keys(self):
        return reversed(self.data.keys())  # 일부러 순서를 바꿔서 반환

my_dict = FakeDict()
my_dict['a'] = 1
my_dict['b'] = 2
my_dict['c'] = 3

print(list(my_dict.keys()))  
# 출력: ['c', 'b', 'a']  (순서가 변경됨)
  • FakeDict는 dict처럼 보이지만 실제 dict가 아니므로, 키 삽입 순서가 보장되지 않는다.
  • keys() 메서드에서 순서를 의도적으로 뒤집으면, dict처럼 사용하던 코드가 예상과 다르게 동작할 수 있다.
  • 이런 문제가 발생하는 이유는 덕 타이핑(Duck Typing) 방식으로 인해, dict와 호환될 것이라고 가정하고 사용했기 때문이다.

딕셔너리를 조심스럽게 다루는 방법

  1. 삽입 순서 보존에 의존하지 않는 코드 작성

    • 딕셔너리를 사용할 때 순서가 중요한 경우 OrderedDict를 고려하는 것이 좋다.
  2. 실행 시점에 dict 타입 검사

     if isinstance(obj, dict):
         print("이 객체는 딕셔너리입니다.")
    
  3. 타입 애너테이션과 정적 분석 사용 (mypy 등)

     def process_data(data: dict[str, int]) -> None:
         pass
    
    • dict[str, int] 타입을 명시하면, 다른 딕셔너리 유사 객체가 들어오는 경우 정적 분석에서 감지할 수 있다.

기억해야 할 내용

  • 파이썬 3.7부터는 dict의 삽입 순서가 유지되므로, 이를 활용할 수 있다.
  • 그러나 딕셔너리와 비슷한 객체들은 삽입 순서를 유지하지 않을 수도 있으므로 주의해야 한다.
  • 딕셔너리와 유사한 클래스를 안전하게 다루려면
    1. 삽입 순서에 의존하지 않는 코드 작성
    2. 실행 시점에 명시적으로 dict 타입을 검사
    3. 타입 애너테이션과 정적 분석을 활용



2-16 in을 사용하고 KeyError를 처리하기보다는 get을 사용하라

  • 딕셔너리의 기본 연산:
    1. 키에 접근 (dict[key])
    2. 키에 값 대입 (dict[key] = value)
    3. 키 삭제 (del dict[key])
  • 딕셔너리는 동적 데이터 구조이므로, 특정 키가 존재하지 않을 가능성을 항상 고려해야 한다.

get() 메서드란?

get() 메서드는 딕셔너리에서 키를 찾을 수 없을 때 기본값을 반환하는 메서드이다.

예제: 일반적인 딕셔너리 접근 방식 (KeyError 발생 가능)

student_scores = {'Kim': 85, 'Lee': 90}

# 존재하지 않는 키에 접근 (KeyError 발생)
score = student_scores['Park']  # KeyError!

get()을 사용하면 안전하게 처리 가능

# 'Park'이 존재하지 않으면 기본값 0을 반환
score = student_scores.get('Park', 0)
print(score)  # 출력: 0

get() 메서드 구조

dictionary.get(key, default_value)
  • key: 찾고자 하는 키
  • default_value: 키가 없을 때 반환할 기본값 (생략 시 None 반환)

KeyError 예외를 사용하는 방식과 비교

1. KeyError를 예외로 처리하는 방식 (비효율적)

try:
    count = counters[key]
except KeyError:
    count = 0

counters[key] = count + 1
  • 단점: KeyError 예외가 발생하면 코드 실행 속도가 느려지고, 코드가 길어진다.

2. get()을 사용한 방식 (더 간결하고 빠름)

count = counters.get(key, 0)
counters[key] = count + 1
  • 장점: 키를 한 번만 읽고, 한 번만 대입하므로 코드가 더 짧고 효율적이다.
  • 카운터와 같은 단순한 데이터 처리에는 get()이 가장 적합하다.

추가적인 딕셔너리 키 처리 방법

1. in을 사용한 방식

if key in counters:
    count = counters[key]
else:
    count = 0

counters[key] = count + 1
  • 단점: in을 사용하면 키를 두 번 검사해야 하므로 비효율적이다.

2. setdefault()를 사용한 방식

counters.setdefault(key, 0)
counters[key] += 1
  • 주의점: setdefault()는 값을 설정할 때 불필요한 연산이 발생할 수도 있다.
  • 대안: 복잡한 값(리스트, 딕셔너리 등)을 기본값으로 설정해야 할 경우, defaultdict를 고려하는 것이 좋다.

3. defaultdict를 사용한 방식 (추천)

from collections import defaultdict

counters = defaultdict(int)  # 기본값이 0인 딕셔너리 생성
counters[key] += 1
  • 장점: 키가 존재하지 않으면 자동으로 기본값(0) 설정.
  • setdefault()보다 더 깔끔하고 효율적이다.

기억해야 할 내용

  • 딕셔너리 키가 없는 경우를 처리하는 방법:
    1. in을 사용하여 검사
    2. KeyError 예외 처리 (try-except)
    3. get() 사용 (간단한 경우에 가장 적합)
    4. setdefault() 사용 (defaultdict가 더 나을 수도 있음)
  • 카운터 같은 기본 데이터 처리에는 get()이 가장 효율적이고 간결한 방법이다.
  • 딕셔너리에 넣을 값을 생성하는 비용이 크거나 예외가 발생할 가능성이 있으면 get()이 더 적절하다.
  • setdefault()를 사용해야 한다면, defaultdict를 고려하는 것이 더 나은 선택일 수 있다.



2-17 내부 상태에서 원소가 없는 경우를 처리할 때는 setdefault보다 defaultdict를 사용하라

  • 직접 생성하지 않은 딕셔너리를 다룰 때, 키가 존재하지 않는 경우를 처리하는 방법이 필요하다.
  • get()을 사용하는 것이 in과 KeyError보다 낫지만, 특정 상황에서는 setdefault()가 더 빠를 수도 있다.
  • 그러나 defaultdict를 사용하면 더욱 깔끔하고 효율적인 코드 작성이 가능하다.

setdefault() vs defaultdict

1. setdefault() 사용 예제

data = {}

# 키가 존재하지 않으면 기본값으로 빈 리스트를 설정
data.setdefault('key1', []).append(10)
data.setdefault('key2', []).append(20)

print(data)
# 출력: {'key1': [10], 'key2': [20]}
  • setdefault()는 키가 존재하지 않으면 기본값을 설정한 후 값을 추가한다.
  • 단점: 매번 setdefault()를 호출해야 하므로 코드가 장황해질 수 있다.

2. defaultdict 사용 예제 (추천)

from collections import defaultdict

data = defaultdict(list)  # 기본값이 리스트인 defaultdict 생성

data['key1'].append(10)
data['key2'].append(20)

print(data)
# 출력: {'key1': [10], 'key2': [20]}

# 디폴트를 5로
my_dict = defaultdict(lambda: 5)

print(my_dict['a'])  # 존재하지 않는 키 접근 -> 5 출력
print(my_dict['b'])  # 존재하지 않는 키 접근 -> 5 출력
print(dict(my_dict))  # {'a': 5, 'b': 5}
  • defaultdict는 키가 없을 경우 자동으로 기본값을 생성해주므로, setdefault()보다 코드가 더 간결해진다.
  • 장점: setdefault()보다 더 직관적이고 사용하기 쉽다.

setdefault()와 defaultdict의 차이점

비교 항목 setdefault() defaultdict
키가 없을 때 기본값을 설정한 후 값 추가 기본값을 자동으로 설정
코드 가독성 반복적인 setdefault() 호출 필요 더 깔끔하고 직관적
성능 setdefault() 호출 시마다 딕셔너리를 수정 기본값이 자동 생성되므로 더 빠름
사용 예 특정 경우 (get()보다 짧은 코드가 필요할 때) 키가 동적으로 추가되는 경우에 적합

기억해야 할 내용

  • 키가 동적으로 추가되는 딕셔너리를 다룰 때는 defaultdict를 사용하는 것이 가장 효율적이다.
  • 직접 생성하지 않은 딕셔너리를 다룰 때는 get()을 우선적으로 사용해야 한다.
  • 코드가 setdefault()를 사용하면 더 짧아지는 경우에는 setdefault()도 고려할 수 있다.
  • 하지만 대부분의 경우 defaultdict가 더 간결하고 직관적인 해결책이다.



2-18 __missing__을 사용해 키에 따라 다른 디폴트 값을 생성하는 방법을 알아두라

  • dict 타입을 상속받아 __missing__ 특별 메서드를 구현하면 키가 없는 경우의 처리 로직을 직접 커스텀할 수 있다.
  • 일반적인 defaultdict는 키 정보를 알 수 없지만, __missing__ 메서드는 키를 활용해 디폴트 값을 생성할 수 있다.

__missing_ 메서드 정리

missing이란?

  • missing은 딕셔너리에서 없는 키를 조회할 때 자동으로 호출되는 메서드
    즉, 딕셔너리에서 키가 없을 때 어떻게 처리할지 직접 정의할 수 있게 해주는 기능.

  • 더 디테일 하게

    __missing__이란?

    딕셔너리에서 없는 키를 조회할 때 자동으로 호출되는 메서드다.

    기본값을 동적으로 생성할 수 있어 defaultdict보다 유연하게 사용할 수 있다.


    1. 기본 사용법

      class MyDict(dict):
          def __missing__(self, key):
              return f"'{key}' 키가 없습니다."
    
      d = MyDict()
      print(d['test'])  # "'test' 키가 없습니다."
    

    키가 없을 때 __missing__이 호출되어 원하는 값이 반환된다.


    2. defaultdict와의 차이

      from collections import defaultdict
    
      d = defaultdict(lambda: "기본값")
      print(d['hello'])  # "기본값"
      print(d['world'])  # "기본값"
    

    defaultdict는 모든 없는 키에 대해 같은 기본값을 반환한다.

      class MyDict(dict):
          def __missing__(self, key):
              return f"'{key}' 키의 길이는 {len(key)}입니다."
    
      d = MyDict()
      print(d['hello'])  # "'hello' 키의 길이는 5입니다."
      print(d['python']) # "'python' 키의 길이는 6입니다."
    

    __missing__은 키별로 다른 기본값을 설정할 수 있다.


    3. defaultdict vs __missing__

    기능 defaultdict __missing__
    없는 키 처리 같은 기본값 반환 키별로 다른 값 반환 가능
    설정 방식 생성 시 함수 지정 __missing__ 메서드에서 정의
    유연성 제한적 유연함

    기본값이 항상 같다면 defaultdict를, 키에 따라 다른 값이 필요하다면 __missing__을 사용하면 된다.

개념

  • dict 클래스의 하위 클래스에서 사용하는 특별 메서드
  • 딕셔너리에서 없는 키에 접근할 때 자동으로 호출됨

특징

  • 키가 없을 때의 동작을 직접 정의 가능
  • 키 값에 따라 다른 기본값 생성 가능
  • defaultdict보다 더 유연한 기본값 처리 가능

기본 사용법

class MyDict(dict):
    def __missing__(self, key):
        value = f"키 '{key}'에 대한 기본값"
        self[key] = value
        return value

d = MyDict()
print(d['test'])  # 키 'test'에 대한 기본값

defaultdict와의 차이

  • defaultdict: 모든 없는 키에 대해 동일한 타입의 기본값 생성
  • missing_: 키별로 다른 기본값을 동적으로 생성 가능

defaultdict의 한계

from collections import defaultdict

def default_factory():
    return "기본값"

data = defaultdict(default_factory)

print(data['없는 키'])  # 출력: "기본값"
  • defaultdict는 키가 없을 때 자동으로 하나의 공통된 값을 반환하지만, 키에 따라 다른 디폴트 값을 생성할 수는 없다.

__missing__을 사용한 dict 하위 클래스 예제

class CustomDict(dict):
    def __missing__(self, key):
        return f"{key}는 존재하지 않습니다."

data = CustomDict()
print(data['없는 키'])
# 출력: "없는 키는 존재하지 않습니다."
  • __missing__ 메서드는 키가 없을 때 호출되며, 키에 따라 커스텀 메시지를 반환할 수 있다.
  • defaultdict와 달리, 사용자가 입력한 키 값을 활용하여 디폴트 값을 생성할 수 있다.

__missing__을 활용한 디폴트 값 생성 예제

class CountDict(dict):
    def __missing__(self, key):
        return len(key)  # 키의 길이를 디폴트 값으로 반환

data = CountDict()
print(data['hello'])   # 출력: 5
print(data['python'])  # 출력: 6
  • __missing__을 이용하면 키 자체를 활용하여 디폴트 값을 동적으로 생성할 수 있다.
  • 위 예제에서는 키의 길이를 디폴트 값으로 반환하도록 구현했다.

기억해야 할 내용

  • 디폴트 값을 생성하는 비용이 높거나 예외가 발생할 가능성이 있다면 setdefault()를 사용하지 않는 것이 좋다.
  • defaultdict는 함수에 인자를 전달할 수 없으므로, 키에 따라 다른 디폴트 값을 생성할 수 없다.
  • 키 정보를 활용한 디폴트 값이 필요하면 dict의 하위 클래스를 만들고 __missing__ 메서드를 직접 정의하면 된다.



반응형
저작자표시 비영리 변경금지 (새창열림)

'리뷰 > 책' 카테고리의 다른 글

[파이썬 코딩의 기술] - 3장 함수  (0) 2025.02.14
[파이썬 코딩의 기술] - 1장 파이썬답게 생각하기  (0) 2025.02.14
Do it! 첫 코딩 - 5장  (0) 2025.02.14
Do it! 첫 코딩 - 4장  (0) 2025.02.14
Do it! 첫 코딩 - 3장  (0) 2025.02.14
'리뷰/책' 카테고리의 다른 글
  • [파이썬 코딩의 기술] - 3장 함수
  • [파이썬 코딩의 기술] - 1장 파이썬답게 생각하기
  • Do it! 첫 코딩 - 5장
  • Do it! 첫 코딩 - 4장
생각 기록실
생각 기록실
AI(LLM)와 서비스 기획을 공부하며 작성하는 기술 블로그입니다. (feat. 영화리뷰를 곁들인..)
    반응형
  • 생각 기록실
    이러쿵 저러쿵
    생각 기록실
  • 전체
    오늘
    어제
  • 링크

    • Github
    • LindeIn
    • 분류 전체보기 (115)
      • 이러쿵 저러쿵 (5)
      • 정보통계 (7)
        • 데이터마이닝 (2)
        • 금융공학 (4)
      • IT (26)
        • Python (10)
        • AWS (5)
        • Github (2)
        • Project (8)
      • 리뷰 (29)
        • 영화 (22)
        • 책 (7)
      • 기타 (48)
  • hELLO· Designed By정상우.v4.10.3
생각 기록실
[파이썬 코딩의 기술] - 2장 리스트와 딕셔너리
상단으로

티스토리툴바