람다 함수 (lambda)
람다 함수는 이름 없이 한 줄로 정의하는 익명 함수입니다.
간단한 연산을 함수로 전달해야 할 때 사용합니다.
# 기본 형태
lambda 매개변수: 표현식
# 일반 함수와 비교
def square(x):
return x ** 2
square_lambda = lambda x: x ** 2
print(square(5)) # 25
print(square_lambda(5)) # 25
람다 함수는 표현식 하나만 가질 수 있으며, return을 명시하지 않아도 결과를 반환합니다.
여러 줄의 로직이 필요하다면 일반 함수를 사용하는 것이 적합합니다.
정렬 기준으로 활용
람다의 가장 실용적인 사용처는 sort()나 sorted()의 key 인자입니다.
samples = [("sample_03", 45.8), ("sample_01", 30.5), ("sample_02", 18.2)]
# 커버리지(두 번째 요소) 기준으로 정렬
samples.sort(key=lambda x: x[1])
print(samples)
# [('sample_02', 18.2), ('sample_01', 30.5), ('sample_03', 45.8)]
# 내림차순
samples.sort(key=lambda x: x[1], reverse=True)
# 문자열 길이 기준 정렬
genes = ["BRCA1", "TP53", "EGFR", "MYC"]
genes.sort(key=lambda g: len(g))
# ['MYC', 'TP53', 'EGFR', 'BRCA1']
map(), filter()와 함께 사용
values = [1, 4, 9, 16, 25]
# map: 각 요소에 함수 적용
roots = list(map(lambda x: x ** 0.5, values))
# [1.0, 2.0, 3.0, 4.0, 5.0]
# filter: 조건에 맞는 요소만 추출
big = list(filter(lambda x: x > 9, values))
# [16, 25]
map()과 filter()는 제너레이터를 반환하므로 list()로 변환해야 결과를 확인할 수 있습니다. 가독성 면에서는 컴프리헨션으로 대체하는 경우가 많습니다.
roots = [x ** 0.5 for x in values]
big = [x for x in values if x > 9]
자주 쓰이는 내장 함수
파이썬이 기본으로 제공하는 내장 함수 중 데이터 처리에서 자주 사용하는 것들을 정리합니다.
수치 관련
abs(-3.5) # 3.5 (절댓값)
round(3.14159, 2) # 3.14 (반올림)
pow(2, 10) # 1024 (거듭제곱)
divmod(17, 5) # (3, 2) (몫과 나머지를 튜플로 반환)
values = [4, 1, 7, 2, 9, 3]
sum(values) # 26
min(values) # 1
max(values) # 9
타입 변환 및 확인
int("150") # 150
float("3.14") # 3.14
str(100) # '100'
bool(0) # False
list((1, 2, 3)) # [1, 2, 3]
tuple([1, 2, 3]) # (1, 2, 3)
set([1, 2, 2, 3]) # {1, 2, 3}
type(3.14) # <class 'float'>
isinstance(3.14, float) # True
isinstance("hello", (str, int)) # True (여러 타입 동시 확인)
isinstance()는 type() ==보다 상속 관계를 고려하므로 타입 확인에 더 권장됩니다.
반복 관련
# range: 숫자 범위 생성
list(range(5)) # [0, 1, 2, 3, 4]
list(range(1, 6, 2)) # [1, 3, 5]
# enumerate: 인덱스와 값 함께 반환
list(enumerate(["a", "b", "c"]))
# [(0, 'a'), (1, 'b'), (2, 'c')]
# zip: 여러 iterable 묶기
list(zip([1, 2, 3], ["a", "b", "c"]))
# [(1, 'a'), (2, 'b'), (3, 'c')]
# reversed: 역순 반복
list(reversed([1, 2, 3])) # [3, 2, 1]
# sorted: 정렬된 새 리스트 반환
sorted([3, 1, 4, 1, 5], reverse=True) # [5, 4, 3, 1, 1]
조건 관련
values = [True, True, False, True]
all(values) # False (모든 요소가 True여야 True)
any(values) # True (하나라도 True이면 True)
# 생물정보학 예시: 모든 샘플이 QC를 통과했는지 확인
qc_results = [30 >= 20, 25 >= 20, 35 >= 20]
print(all(qc_results)) # True
# 어느 하나라도 필터링 기준을 초과하는지 확인
coverages = [18.5, 22.0, 15.3]
print(any(cov < 20 for cov in coverages)) # True
기타 유용한 내장 함수
# len: 길이 반환
len([1, 2, 3]) # 3
len("ATCGATCG") # 8
# id: 객체의 메모리 주소 반환 (is 연산자 이해에 활용)
a = [1, 2, 3]
b = a
print(id(a) == id(b)) # True
# open: 파일 열기 (파일 입출력에서 자세히 다룸)
# help: 독스트링 출력
help(sorted)
# vars, dir: 객체 속성 확인 (디버깅 시 유용)
dir([]) # 리스트가 가진 메서드 목록
collections 모듈
collections 모듈은 파이썬 내장 자료형을 보완하는 특수 컨테이너를 제공합니다.
Counter
요소의 개수를 세는 딕셔너리 서브클래스입니다.
from collections import Counter
# 기본 사용
seq = "ATCGATCGATCG"
counter = Counter(seq)
print(counter)
# Counter({'A': 3, 'T': 3, 'C': 3, 'G': 3})
# 가장 많이 등장하는 요소
print(counter.most_common(2))
# [('A', 3), ('T', 3)]
# 리스트에서 빈도 계산
gene_list = ["TP53", "BRCA1", "TP53", "EGFR", "TP53", "BRCA1"]
gene_count = Counter(gene_list)
print(gene_count)
# Counter({'TP53': 3, 'BRCA1': 2, 'EGFR': 1})
print(gene_count["TP53"]) # 3
print(gene_count["MYC"]) # 0 (없는 키도 0 반환, KeyError 없음)
# 빈도 기준 상위 N개
print(gene_count.most_common(2))
# [('TP53', 3), ('BRCA1', 2)]
defaultdict
존재하지 않는 키에 접근할 때 자동으로 기본값을 생성하는 딕셔너리입니다.
from collections import defaultdict
# 기본값 타입 지정
gene_samples = defaultdict(list)
gene_samples["BRCA1"].append("sample_01")
gene_samples["BRCA1"].append("sample_02")
gene_samples["TP53"].append("sample_01")
print(dict(gene_samples))
# {'BRCA1': ['sample_01', 'sample_02'], 'TP53': ['sample_01']}
# int 기본값 (카운터 용도)
word_count = defaultdict(int)
for gene in ["TP53", "BRCA1", "TP53"]:
word_count[gene] += 1
print(dict(word_count))
# {'TP53': 2, 'BRCA1': 1}
일반 딕셔너리는 없는 키에 접근하면 KeyError가 발생하지만, defaultdict는 지정한 타입의 기본값을 자동으로 생성합니다.
OrderedDict
삽입 순서를 보장하는 딕셔너리입니다. 파이썬 3.7 이상에서는 일반 딕셔너리도 삽입 순서를 유지하므로 대부분의 경우 일반 딕셔너리로 대체됩니다. 순서 비교 기능이 필요한 경우에 사용합니다.
from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
# 순서를 포함한 비교
od1 = OrderedDict([("a", 1), ("b", 2)])
od2 = OrderedDict([("b", 2), ("a", 1)])
print(od1 == od2) # False (순서가 다르면 다른 것으로 취급)
namedtuple
필드 이름을 가진 튜플입니다. 인덱스 대신 이름으로 값에 접근할 수 있어 가독성이 높습니다.
from collections import namedtuple
# 정의
Sample = namedtuple("Sample", ["id", "species", "coverage"])
# 생성
s = Sample(id="sample_01", species="Homo sapiens", coverage=30.5)
# 접근
print(s.id) # sample_01
print(s.coverage) # 30.5
print(s[0]) # sample_01 (인덱스로도 접근 가능)
# 언패킹
sample_id, species, coverage = s
튜플의 불변성을 유지하면서 이름으로 필드에 접근할 수 있어, 간단한 데이터 구조를 표현할 때 유용합니다.
deque
양쪽 끝에서 빠르게 추가와 삭제가 가능한 자료구조입니다. 리스트는 맨 앞에서의 추가/삭제가 느린 반면, deque는 양쪽 모두 O(1)로 처리합니다.
from collections import deque
dq = deque([1, 2, 3])
dq.append(4) # 오른쪽에 추가
dq.appendleft(0) # 왼쪽에 추가
dq.pop() # 오른쪽에서 제거
dq.popleft() # 왼쪽에서 제거
# maxlen 설정: 최근 N개만 유지
recent = deque(maxlen=3)
for i in range(5):
recent.append(i)
print(recent) # deque([2, 3, 4], maxlen=3)
슬라이딩 윈도우 방식으로 최근 N개의 데이터만 유지해야 할 때 유용합니다.
정리표
| 항목 | 주요 용도 |
| lambda | 간단한 익명 함수, key 인자 전달 |
| map() | 각 요소에 함수 적용 |
| filter() | 조건에 맞는 요소 추출 |
| all() / any() | 전체/일부 조건 충족 여부 확인 |
| isinstance() | 타입 확인 |
| Counter | 요소 빈도 계산 |
| defaultdict | 기본값 있는 딕셔너리 |
| namedtuple | 이름 있는 튜플 |
| deque | 양방향 빠른 추가/삭제 |
'BI&Programming-Tools > Python' 카테고리의 다른 글
| [파이썬 기초] 정규표현식 (re 모듈) (0) | 2026.06.17 |
|---|---|
| [파이썬 기초] 함수 정의와 인자 (*args, **kwargs) (0) | 2026.06.16 |
| [파이썬 기초] 반복문 (while, for, comprehension) (0) | 2026.06.16 |
| [파이썬 기초] 조건문과 연산자 (0) | 2026.06.15 |
| [파이썬 기초] print / input / 주석 (0) | 2026.06.15 |
