문법 기초

hizikang01·2025년 4월 24일

python

목록 보기
2/2

목차


1-1. 리스트 + 슬라이싱 패턴

1. 개념

  • 리스트(List)는 파이썬에서 가장 기본적인 순서가 있는 자료구조
  • 요소의 추가, 삭제, 접근, 슬라이싱이 자유로우며, 다양한 문제에서 기본 단위로 활용됨

리스트 vs 딕셔너리 차이점

항목리스트딕셔너리
인덱스정수형 (0, 1, 2, ...)키 기반 (문자열, 숫자 등 자유)
순서있음Python 3.7 이상부터 순서 유지됨
주요 기능순차 접근, 슬라이싱빠른 검색, 키-값 매핑
사용 예배열, 정렬, 인덱스 기반 접근이름 기반 매핑, 카운팅, 해시 테이블

2. 문법 / 예시 코드

# 리스트 생성
arr = [1, 2, 3, 4, 5]

# 인덱싱
print(arr[0])  # 1
print(arr[-1])  # 5 (역방향 인덱스)

# 슬라이싱
print(arr[1:4])  # [2, 3, 4]
print(arr[:3])   # [1, 2, 3]
print(arr[::2])  # [1, 3, 5] (2칸씩 건너뜀)

# 리스트 메서드
arr.append(6)
arr.insert(2, 99)
arr.remove(3)  # 첫 번째 3 제거
arr.pop()      # 마지막 요소 제거
arr.sort()     # 오름차순 정렬
arr.reverse()  # 뒤집기

3. 자주 쓰는 패턴

# 1. 리스트 컴프리헨션 (조건 포함 반복)
squares = [x**2 for x in range(1, 6)]  # X^2의 값이 리스트에 들어감 [1, 4, 9, 16, 25]
evens = [x for x in arr if x % 2 == 0]  # 짝수만 추출

# 2. 2차원 리스트 만들기
matrix = [[0]*3 for _ in range(4)]  # 4행 3열 0으로 초기화 / 변수 사용하지 않을 때 _사용
matrix = [[0]*3]*4 # --> 같은 리스트를 4번 복사 / 내부 리스트는 전부 같은 참조값을 공유 / 사용X

# 3. 리스트 뒤집기 / 정렬된 복사본
rev = arr[::-1]
sorted_arr = sorted(arr)

패턴 설명

  • 리스트 컴프리헨션은 가장 자주 쓰는 반복구조 → 깔끔하고 빠름
  • 슬라이싱은 리스트 자르기, 뒤집기 등에서 자주 사용

대표 문제


1-2. 딕셔너리

1. 개념

  • 딕셔너리(dict): key-value 형태 / 빠른 검색과 매핑에 유리

2. 문법 / 예시 코드

# 딕셔너리 생성
scores = {'math': 90, 'eng': 85}
print(scores['math'])  # 90

# 값 추가/수정/삭제
scores['kor'] = 80
scores['eng'] = 95
del scores['math'] #삭제

# key/value 확인
print(scores.keys())  # dict_keys(['eng', 'kor'])
print(scores.values())

3. 자주 쓰는 패턴

# 빈도수 세기
freq = {}
for x in data: # data의 각 요소 x에 대해 반복
	# freq dic에 x라는 key가 이미 있으면 기존 값에 +1
    # 없으면 0에서 시작해 +=1
    freq[x] = freq.get(x, 0) + 1

패턴 설명

  • .get(x, 0) 패턴은 딕셔너리 key 존재 여부를 처리할 때 깔끔함 / 딕셔너리에서 안전하게 값꺼내기 --> get()

4. 대표 문제


1-3. set 자료형과 중복 제거 / 교집합

1. 개념

  • set: 중복이 없는 집합 자료형
  • 순서가 없으며, 집합 연산(합집합, 교집합 등)에 강함

2. 문법 / 예시 코드

s = set([1, 2, 3, 3, 2])  # 중복 제거
s.add(4)
s.remove(2) #s = {1, 3, 4}

# 집합 연산
a = set([1, 2, 3])
b = set([2, 3, 4])
print(a & b)  # 교집합 {2, 3}
print(a | b)  # 합집합 {1, 2, 3, 4}
print(a - b)  # 차집합 {1}

3. 자주 쓰는 패턴

# 중복 제거 리스트 만들기
unique = list(set(my_list))

# 두 리스트의 공통 요소
common = set(list1) & set(list2)

# 집합으로 포함 여부 체크 → O(1)
if x in my_set:
    pass

패턴 설명

  • 리스트 중복 제거는 항상 set() 사용
  • 포함 여부 판단은 in setin list보다 훨씬 빠름 (O(1))
  • 집합 연산 &, |, -는 직관적이고 읽기 쉬움

4. 대표 문제


1-4. 튜플과 불변형 구조

1. 개념

  • 튜플(tuple)은 리스트와 유사하지만 변경 불가능(immutable)한 자료형
  • 한 번 정의되면 내부 요소를 수정할 수 없기 때문에 읽기 전용 데이터에 적합
  • 딕셔너리의 키, set의 요소 등 변경 불가능한 구조가 필요한 곳에서 활용됨

2. 문법 / 예시 코드

# 튜플 생성
point = (3, 4)

# 요소 접근
print(point[0])  # 3
print(point[1])  # 4

# 불변성 확인 (오류 발생 예)
# point[0] = 1  # TypeError: 'tuple' object does not support item assignment

# 튜플 언팩킹
x, y = point
print(x, y)  # 3 4

# 튜플로 여러 값 반환
def get_min_max(arr):
    return min(arr), max(arr)

mn, mx = get_min_max([1, 2, 3])
print(mn, mx)  # 1 3

3. 자주 쓰는 패턴

# 튜플 언팩킹
for idx, value in enumerate(['a', 'b', 'c']):
    print(idx, value)

# 딕셔너리 key-value 튜플 순회
my_dict = {'a': 1, 'b': 2}
for k, v in my_dict.items():
    print(k, v)

패턴 설명

  • 튜플은 값을 변경하지 않을 때 안전하게 사용할 수 있는 구조
  • (x, y) 좌표나 RGB 색상처럼 의미 있는 값 2-3개를 한 덩어리로 만들고, 수정될 일이 없을 때 사용
  • 함수 리턴값이 여러 개일 때 (a, b) 형태 튜플로 많이 사용됨
  • .items()(key, value) 형태의 튜플을 순회함

4. 대표 문제


1-5. 기본 정렬 방법 (sort, sorted, key)

1. 개념

  • 파이썬에서는 기본 정렬 방법으로 sort()sorted()를 제공
  • sort() 원본 변경, 리스트 전용
  • sorted() 원본 유지 / 안전하고 직관적 / 파이프라인 처럼 한줄에 처리 / 기존 리스트 복사 후 정렬해서 새 리스트를 만들어서 반환
  • keyreverse 인자를 활용해 정렬 조건을 커스터마이징 가능

2. 문법 / 예시 코드

arr = [5, 2, 9, 1]

arr.sort()  # 원본 리스트 정렬
print(arr)  # [1, 2, 5, 9]

arr = [5, 2, 9, 1]
sorted_arr = sorted(arr)  # 원본 유지, 복사본 정렬
print(sorted_arr)  # [1, 2, 5, 9]

# 내림차순 정렬
arr.sort(reverse=True)

# key 기준 정렬 (길이순, 알파벳순 등)
words = ['banana', 'apple', 'cherry']
print(sorted(words, key=len))  # ['apple', 'banana', 'cherry']

3. 자주 쓰는 패턴

# 튜플 정렬: 두 번째 기준으로 정렬
pairs = [(1, 'b'), (3, 'a'), (2, 'c')]
pairs.sort(key=lambda x: x[1])  

# 리스트 내부 딕셔너리 정렬
people = [{'name': 'Tom', 'age': 30}, {'name': 'Sue', 'age': 25}]
people.sort(key=lambda x: x['age'])

패턴 설명

  • lambda를 활용한 key 정렬은 거의 모든 실전 정렬 문제에서 사용됨
  • key=lambda x: -x를 사용하면 숫자 내림차순도 가능

4. 대표 문제


1-6. lambda 함수 활용 정리 (map, filter, key 정렬)

1. 개념

  • lambda 함수는 이름 없는 익명 함수로, 간단한 계산/로직을 한 줄로 표현할 수 있음
  • 반복문/정렬/map/filter 등에서 보조 함수로 자주 사용됨

2. 문법 / 예시 코드

# 기본 형태
lambda x: x + 1
lambda x, y: x * y

# 정렬 기준 (문자 길이)
words = ['banana', 'apple', 'cherry']
sorted(words, key=lambda x: len(x))  # ['apple', 'banana', 'cherry'] # 입력 x를 받아서 len(x) 반환

# 리스트 안 딕셔너리 정렬
people = [{'name': 'Tom', 'age': 30}, {'name': 'Sue', 'age': 25}]
people.sort(key=lambda x: x['age'])  # [{'name': 'Sue', 'age': 25}, {'name': 'Tom', 'age': 30}]

# map: 변환 처리
nums = [1, 2, 3]
squares = list(map(lambda x: x**2, nums))  # [1, 4, 9]

# filter: 조건 필터링
even = list(filter(lambda x: x % 2 == 0, nums))  # [2]

3. 자주 쓰는 패턴

# 문자열 길이 기준 정렬
sorted(words, key=lambda x: len(x))

# 튜플 내 문자 기준 정렬
pairs = [(1, 'b'), (3, 'a'), (2, 'c')]
pairs.sort(key=lambda x: x[1])
# x[0] --> 숫자, x[1] --> 문자 / 따라서 문자 기준으로 정렬

# 딕셔너리에서 특정 필드 기준 정렬
people.sort(key=lambda x: x['age'])

# map으로 제곱 리스트 만들기
list(map(lambda x: x**2, nums))

# filter로 짝수만 남기기
list(filter(lambda x: x % 2 == 0, nums))

4. 패턴 설명

  • lambda는 간단한 처리를 위해 함수 대신 사용됨
  • key=lambda ...은 튜플, 문자열, 딕셔너리의 정렬 기준을 자유롭게 지정할 수 있어 유연함
  • map: 리스트 전체 함수에 적용 filter: 조건에 맞는 요소만 추출

5. 대표 문제


1-7. 내장함수 정리 (zip, enumerate, range, sum, max, min)

1. 개념

  • 파이썬 내장 함수들은 반복, 합계, 최댓값 등 자주 쓰이는 기본 동작을 쉽게 처리할 수 있게 해줌
  • 외부 모듈 없이 바로 사용 가능하고 코드 간결화에 효과적

2. 문법 / 예시 코드

# zip: 여러 리스트 병렬 순회
names = ['Tom', 'Sue']
ages = [30, 25]
for name, age in zip(names, ages):
    print(name, age)

# enumerate: 인덱스 함께 반환
for idx, val in enumerate(['a', 'b', 'c']):
    print(idx, val)

# range: 숫자 범위 생성
for i in range(3):
    print(i)  # 0, 1, 2

# sum / max / min
nums = [3, 1, 5]
print(sum(nums))  # 9
print(max(nums))  # 5
print(min(nums))  # 1

3. 자주 쓰는 패턴

# enumerate: 튜플 언팩킹
for idx, value in enumerate(['a', 'b', 'c']):
    print(idx, value)

# zip: 리스트 병렬 순회
names = ['Tom', 'Sue']
ages = [30, 25]
for name, age in zip(names, ages):
    print(name, age)

# range + len: 인덱스로 반복 제어
for i in range(len(data)):
    print(i, data[i])

# sum / max / min: 집계 함수
print(sum([1, 2, 3]))  # 6
print(max([1, 2, 3]))  # 3
print(min([1, 2, 3]))  # 1

4. 패턴 설명

  • enumerate()는 반복문에서 인덱스를 자동으로 함께 제공
  • zip()은 두 리스트를 동시에 순회할 때 유용
  • range()는 숫자 기반 반복에 필수
  • sum(), max(), min()은 집계 함수로 빠르게 요약 정보를 구할 수 있음

5. 대표 문제


1-8. itertools 정리 (permutations, combinations)

1. 개념

  • itertools는 순열, 조합, 중복 조합 등의 기능 제공
  • permutations : 순열 (순서O) / 완전탐색, 비밀번호 찾기, 자리배치
  • combinations : 조합 (순서X) / 부분집합, 팀 짜기, 가능한 경우의 수

2. 문법 / 예시 코드

from itertools import permutations, combinations

# 순열
perm = list(permutations([1, 2, 3], 2))
# [(1,2), (1,3), (2,1), (2,3), ...]

# 조합
comb = list(combinations([1, 2, 3], 2))
# [(1,2), (1,3), (2,3)]

3. 자주 쓰는 패턴

# 전체 순열 생성 후 조건 검사
for case in permutations(nums, 3): 
# nums에서 3개를 뽑아서 만들 수 있는 모든 순열(순서 O) / 그 순열을 case에 담아서 반복
    if sum(case) == 10: # case의 값들을 더해서 10이면 print
        print(case)

# 조합을 이용한 경우의 수 비교
for a, b in combinations(students, 2):
# students 리스트에서 2명씩 조합 생성 (순서 X, 중복 x) / 각 조합은 (a, b) 형태의 튜플 2개로 언팩킹
    if a[0] != b[0]: # a와b의 0번 인덱스가 다른 경우
        count += 1 # 그 조건을 만족하는 조합의 개수는?

패턴 설명

  • 순서가 중요하면 permutations, 아니면 combinations
  • permutations : r개를 뽑는 모든 순열 생성
  • combinations : r개를 뽑는 모든 조합 생성 (순서 X)
  • 완전 탐색/브루트포스 문제에서 매우 자주 사용됨
  • 정렬된 결과를 기준으로 조건 체크할 때 유리함

4. 대표 문제


1-9. collections 정리 (deque, defaultdict, Counter)

1. 개념

  • collections는 파이썬의 고급 자료구조 모듈
  • deque: 양방향 큐 / 빠른 삽입,삭제
    BFS 구현 / 슬라이딩 윈도우, 투포인터 / 큐 자료구조 대체 할 때
  • defaultdict: 기본값을 지정할 수 있는 딕셔너리 / 일반 dict는 없는 키에 접근하면 KeyError / 지정한 기본값을 자동 생성해줌
    빈도수 누적 / 리스트 형태로 그룹핑 / dict[key] += 1 식 코드 짤 때 KeyError 방지
  • Counter: 리스트 내 요소의 빈도수 세기

2. 문법 / 예시 코드

from collections import deque, defaultdict, Counter

# deque
dq = deque([1, 2, 3])
dq.append(4) # [1, 2, 3, 4]
dq.appendleft(0) # [0, 1, 2, 3, 4]
dq.pop() # [0, 1, 2, 3]
dq.popleft() # [1, 2, 3]

# defaultdict
dd = defaultdict(int)
dd['a'] += 1 # {'a':1} --> 초기값 없이 자동 생성 
# defaultdict(int) → 기본값 0 / defaultdict(list) → 기본값 []

# Counter
cnt = Counter('hello')
print(cnt['l'])  # 2
cnt.most_common(1) → 가장 많이 나온 요소 1: [('l', 2)]

#cnt.most_common
most_common = cnt.most_common(n)[0] # 상위 n개의 리스트 / [0] : n개중 첫번째 값

3. 자주 쓰는 패턴

# BFS에서 deque 활용
from collections import deque
queue = deque([start])
while queue:
    cur = queue.popleft()
    ...

# defaultdict로 카운트 초기화
freq = defaultdict(int)
for ch in s:
    freq[ch] += 1

패턴 설명

  • deque는 BFS에서 큐보다 훨씬 빠르고 효율적임
  • defaultdict는 키 없을 때 기본값 자동 생성 → 코드 간결화
  • Counter는 빈도 기반 정렬이나 비교에 매우 유용

4. 대표 문제


1-10. heapq (우선순위 큐), bisect (이진탐색용)

1. 개념

  • heapq: 최소 힙(우선순위 큐)을 구현하는 모듈
    우선 순위 높은 값부터 처리하고 싶을 때 사용
  • bisect: 정렬된 리스트에서 이진 탐색으로 삽입 위치 찾는 모듈

2. 문법 / 예시 코드

import heapq

# 최소 힙
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
print(heapq.heappop(heap))  # 1

# 최대 힙 구현: 음수로 저장
heapq.heappush(heap, -5)
heapq.heappop(heap)  # -5

# bisect
from bisect import bisect_left, bisect_right
arr = [1, 2, 4, 4, 4, 7]
left = bisect_left(arr, 4) # 4보다 크거나 같은 첫번째 인덱스 (왼쪽기준) --> 2
right = bisect_right(arr, 4) # 4보다 큰 첫 인덱스 (오른쪽기준) --> 5
print(right - left)  # 5-2 = 3

bisect_leftbisect_right정렬된 리스트에서 특정 값의 등장 범위를 찾는 데 사용됨
right-left는 그 값의 총 개수(count) 를 의미

3. 자주 쓰는 패턴

## heap
# 최소값을 빠르게 꺼내는 구조
nums = [5, 3, 9, 1]
heapq.heapify(nums)  # 리스트를 힙 구조로 변환

while nums:
    print(heapq.heappop(nums))  # 가장 작은 값부터 꺼냄

#최대 힙 (음수로 넣기)
nums = [5, 3, 9, 1]
max_heap = []
for n in nums:
    heapq.heappush(max_heap, -n)  # 음수로 넣기

while max_heap:
    print(-heapq.heappop(max_heap))  # 원래 값 복원

# bisect 
# 특정 숫자의 개수 세기
arr = [1, 2, 4, 4, 4, 7]
cnt = bisect_right(arr, 4) - bisect_left(arr, 4)
print(cnt)  # 5-2 = 3

# 값이 특정 구간에 있는 요소 개수
arr = [1, 3, 5, 7, 9]
left = bisect_left(arr, 3) # 1
right = bisect_right(arr, 7) # 4
print(right - left)  # 4-1 = 3 

패턴 설명

  • heapq는 다익스트라, 탐욕 알고리즘에서 핵심 도구
    최소 거리 노드 우선 처리 / 가장 작은,큰 값 K개 뽑기 / 데이터가 계속 들어올 때 최적 순위 유지
  • bisect는 정렬된 리스트에서 탐색/삽입 위치 빠르게 찾음
    정렬 된 배열에서 범위 값 카운트 / 특정 값이 있는 구간 체크
    슬라이딩 윈도우 범위 개수 체크 / 값의 등장 횟수 계산

4. 대표 문제


0개의 댓글