3 분 소요

이 장에서 배울 것

이번 장에서는 파이썬 자료구조(data structure)를 배웁니다. 자료구조는 데이터를 담는 그릇입니다. 생물정보학에서는 유전자 목록, 샘플 정보, 발현량, 변이 위치처럼 여러 데이터를 한꺼번에 다루므로 자료구조가 매우 중요합니다.

핵심 용어를 먼저 정리하겠습니다.

  • 리스트(list): 여러 값을 순서대로 담는 자료구조입니다.
  • 인덱스(index): 리스트 안에서 값의 위치를 나타내는 번호입니다.
  • 튜플(tuple): 리스트와 비슷하지만 보통 바꾸지 않는 묶음으로 씁니다.
  • 딕셔너리(dictionary): 키(key)와 값(value)을 짝으로 저장하는 자료구조입니다.
  • 집합(set): 중복을 허용하지 않는 값들의 모음입니다.
  • 중첩 구조(nested structure): 자료구조 안에 다른 자료구조가 들어 있는 형태입니다.
  • 컴프리헨션(comprehension): 반복문을 짧게 써서 새 리스트 등을 만드는 문법입니다.

Python 자료구조

가장 쉬운 비유: 여러 종류의 상자

자료구조는 데이터를 담는 상자입니다. 그런데 상자마다 성격이 다릅니다.

  • 리스트는 줄 세운 상자입니다.
  • 딕셔너리는 이름표가 붙은 사물함입니다.
  • 집합은 중복 입장을 막는 출입 명단입니다.
  • 튜플은 한 번 정하면 잘 바꾸지 않는 묶음입니다.

데이터 성격에 맞는 상자를 고르는 것이 중요합니다.

리스트: 순서 있는 목록

리스트는 여러 값을 순서대로 담습니다.

genes = ["BRCA1", "TP53", "EGFR"]
print(genes[0])

파이썬 인덱스는 0부터 시작합니다. 그래서 genes[0]은 첫 번째 값인 BRCA1입니다.

리스트에 값을 추가할 수도 있습니다.

genes.append("MYC")
print(genes)

생물정보학에서는 유전자 목록, 샘플 목록, 파일 목록을 리스트로 자주 다룹니다.

슬라이싱: 일부만 꺼내기

리스트에서 일부 구간만 꺼낼 수 있습니다.

numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])

결과는 [20, 30, 40]입니다. 1:4는 인덱스 1부터 4 바로 전까지라는 뜻입니다.

튜플: 바꾸지 않을 묶음

튜플은 괄호로 만듭니다.

position = ("chr1", 12345)

이것은 1번 염색체의 12345 위치처럼 서로 연결된 값을 묶을 때 쓸 수 있습니다. 입문 단계에서는 “튜플은 리스트와 비슷하지만 보통 바꾸지 않는 묶음”이라고 이해하면 충분합니다.

딕셔너리: 키와 값

딕셔너리는 이름표와 값을 짝으로 저장합니다.

expression = {
    "BRCA1": 12.5,
    "TP53": 8.2,
    "EGFR": 20.1
}

print(expression["EGFR"])

EGFR이라는 키로 20.1이라는 값을 꺼냅니다. 유전자별 발현량처럼 “이름 → 값” 구조는 딕셔너리에 잘 맞습니다.

딕셔너리 값 바꾸기와 추가하기

expression["TP53"] = 9.0
expression["MYC"] = 15.2

첫 줄은 기존 값을 바꾸고, 둘째 줄은 새 값을 추가합니다.

집합: 중복 없는 모음

집합은 중복을 제거합니다.

genes = ["BRCA1", "TP53", "BRCA1", "EGFR"]
unique_genes = set(genes)
print(unique_genes)

결과에는 BRCA1이 한 번만 들어갑니다. 중복 유전자 이름을 제거할 때 유용합니다.

중첩 구조

실제 데이터는 단순하지 않습니다. 샘플마다 여러 정보를 저장해야 할 수 있습니다.

samples = {
    "sample1": {"group": "cancer", "age": 52},
    "sample2": {"group": "normal", "age": 48}
}

print(samples["sample1"]["group"])

결과는 cancer입니다. 딕셔너리 안에 딕셔너리가 들어 있는 구조입니다.

컴프리헨션: 짧게 만드는 반복문

다음 코드는 발현량이 10 이상인 값만 골라 새 리스트를 만듭니다.

values = [3, 12, 8, 20]
high_values = [v for v in values if v >= 10]
print(high_values)

결과는 [12, 20]입니다. 처음에는 어려워 보이면 일반 반복문부터 익히고, 나중에 컴프리헨션을 써도 됩니다.

어떤 자료구조를 고를까

유전자 이름을 순서대로 저장하려면 리스트가 좋습니다.

genes = ["BRCA1", "TP53", "EGFR"]

유전자별 발현량을 저장하려면 딕셔너리가 좋습니다.

expression = {"BRCA1": 12.5, "TP53": 8.2}

중복 유전자 이름을 제거하려면 집합이 좋습니다.

unique_genes = set(genes)

생물정보학에서 왜 중요한가

생물정보학 데이터는 “이름과 값”이 많습니다. 유전자 이름과 발현량, 샘플 이름과 질병 여부, 변이 위치와 변이 종류처럼 짝지어진 데이터가 많습니다. 자료구조를 잘 고르면 코드가 짧고 명확해집니다.

실전 감각: 데이터 모양에 맞는 그릇 고르기

자료구조를 고르는 기준은 “내 데이터가 어떤 모양인가”입니다. 유전자 이름을 순서대로 저장하려면 리스트가 편합니다.

genes = ["BRCA1", "TP53", "EGFR"]

유전자마다 발현량을 연결하려면 딕셔너리가 더 자연스럽습니다.

expression = {"BRCA1": 12.5, "TP53": 8.2, "EGFR": 20.1}

중복을 제거하려면 집합을 씁니다.

unique_genes = set(["BRCA1", "TP53", "BRCA1"])

실제 샘플 정보는 중첩 딕셔너리로 표현할 수 있습니다.

samples = {
    "S1": {"group": "cancer", "age": 52},
    "S2": {"group": "normal", "age": 48}
}

초보자가 자주 하는 실수는 딕셔너리에 없는 key를 꺼내려 하거나, set이 순서를 보존하는 목록이라고 착각하는 것입니다. set은 중복 제거에는 좋지만 순서가 중요한 분석에는 맞지 않을 수 있습니다.

미니 실습 블록: 리스트와 딕셔너리로 metadata 표현하기

이 실습은 리스트와 딕셔너리로 metadata 표현하기를 직접 손으로 확인하는 연습입니다. 왜 필요한가 하면, 샘플 정보는 표로 저장되지만 코드 안에서는 리스트와 딕셔너리 구조로 자주 다루기 때문입니다.

samples = [
    {"sample_id": "S1", "condition": "control", "batch": "B1"},
    {"sample_id": "S2", "condition": "treated", "batch": "B1"},
    {"sample_id": "S3", "condition": "control", "batch": "B2"},
]

for sample in samples:
    if sample["condition"] == "control":
        print(sample["sample_id"])

각 코드 요소의 의미를 풀어보면 다음과 같습니다. 리스트 안의 각 딕셔너리는 한 샘플의 정보를 뜻합니다. "sample_id" 같은 키로 값을 꺼내 조건을 확인할 수 있습니다.

생물정보학/계산생물학에서 쓰이는 장면은 분명합니다. metadata table의 각 행을 샘플 딕셔너리 하나로 생각하면 pandas DataFrame을 이해하기 쉬워집니다.

흔한 오해 또는 주의점도 있습니다. 같은 sample_id 키가 중복되면 뒤 값이 앞 값을 덮을 수 있으므로 중복 ID를 조심해야 합니다.

핵심 정리

리스트는 순서 있는 목록, 딕셔너리는 키와 값의 짝, 집합은 중복 없는 모음, 튜플은 바꾸지 않을 묶음입니다. 자료구조는 데이터를 담는 그릇이므로, 데이터의 성격에 맞게 고르는 것이 중요합니다.

문제 풀이

Python 자료구조

0 / 40
Gemini AI 채점

주관식 답안은 Gemini API로 채점합니다. API 키는 이 브라우저에만 저장됩니다.

API KEY 미등록
  1. 1. [쉬움] 객관식

    리스트(list)의 설명으로 적절한 것은?

    선택지
  2. 2. [쉬움] 객관식

    파이썬 리스트의 첫 번째 값은 보통 몇 번 인덱스로 꺼내는가?

    선택지
  3. 3. [코드] 객관식

    genes = ["BRCA1", "TP53", "EGFR"]에서 genes[1]은?

    선택지
  4. 4. [쉬움] 객관식

    리스트에 새 값을 추가할 때 본문에서 사용한 메서드는?

    선택지
  5. 5. [쉬움] 객관식

    딕셔너리(dictionary)의 설명으로 적절한 것은?

    선택지
  6. 6. [코드] 객관식

    expression["EGFR"]의 의미로 적절한 것은?

    선택지
  7. 7. [쉬움] 객관식

    집합(set)의 특징으로 적절한 것은?

    선택지
  8. 8. [계산] 객관식

    set(["A", "A", "B"])에 들어 있는 고유 값 개수는?

    선택지
  9. 9. [보통] 객관식

    튜플(tuple)의 입문용 설명으로 적절한 것은?

    선택지
  10. 10. [코드] 객관식

    numbers = [10,20,30,40,50]에서 numbers[1:4] 결과는?

    선택지
  11. 15. [보통] 객관식

    유전자별 발현량처럼 “이름 → 값” 구조에 가장 잘 맞는 것은?

    선택지
  12. 16. [쉬움] 객관식

    유전자 이름 목록처럼 순서대로 여러 값을 담기에 적절한 것은?

    선택지
  13. 17. [보통] 객관식

    중첩 구조(nested structure)의 설명으로 적절한 것은?

    선택지
  14. 18. [코드] 객관식

    samples["sample1"]["group"]처럼 쓰는 이유로 적절한 것은?

    선택지
  15. 19. [보통] 객관식

    컴프리헨션(comprehension)의 설명으로 적절한 것은?

    선택지
  16. 20. [코드] 객관식

    [v for v in [3,12,8,20] if v >= 10]의 결과는?

    선택지
  17. 25. [보통] 객관식

    샘플 이름과 질병 여부를 저장할 때 적절한 구조는?

    선택지
  18. 26. [쉬움] 객관식

    중복 유전자 이름을 제거할 때 적절한 자료구조는?

    선택지
  19. 27. [코드] 객관식

    다음 코드의 출력은? d={"A":1}; d["B"]=2; print(d["B"])

    선택지
  20. 28. [보통] 객관식

    자료구조를 잘 고르는 것이 중요한 이유는?

    선택지
  21. 29. [중간] 객관식

    genes = ["BRCA1", "TP53", "EGFR"]에서 genes[0]의 값은?

    선택지
  22. 30. [중간] 객관식

    유전자 이름마다 발현량을 연결해 저장하기 가장 적절한 자료구조는?

    선택지
  23. 31. [중간] 객관식

    set(["A", "B", "A"])의 핵심 효과는?

    선택지
  24. 32. [중간] 객관식

    samples["S1"]["group"]이 의미하는 것은?

    선택지
  25. 33. [중간] 객관식

    values=[3,12,8,20]일 때 [v for v in values if v >= 10]의 결과는?

    선택지
  26. 34. [중간] 객관식

    샘플별 group, age, sex처럼 여러 속성을 함께 저장하기 좋은 구조는?

    선택지
  27. 35. [중간] 객관식

    딕셔너리에서 없는 key를 바로 꺼내려 할 때 생길 수 있는 문제는?

    선택지
  28. 36. [중간] 객관식

    순서가 중요한 유전자 목록을 보관할 때 set만 쓰는 것이 위험한 이유는?

    선택지
  29. 37. [실전] 객관식

    sample['condition'] == 'control'의 의미는?

    선택지
  30. 38. [실전] 객관식

    sample_id로 condition을 빠르게 찾을 때 적절한 자료구조는?

    선택지
  31. 주관식 39. [실습] 주관식 · Gemini 채점

    유전자 목록 BRCA1, TP53, EGFR을 리스트로 만들고 첫 번째 값을 출력하는 코드를 작성하라.

  32. 주관식 40. [실습] 주관식 · Gemini 채점

    유전자별 발현량 BRCA1: 12.5, TP53: 8.2를 딕셔너리로 만들고 BRCA1 값을 출력하라.

  33. 주관식 41. [실습] 주관식 · Gemini 채점

    리스트 genesMYC를 추가하는 코드를 작성하라.

  34. 주관식 42. [실습] 주관식 · Gemini 채점

    리스트 ["BRCA1", "TP53", "BRCA1"]에서 중복을 제거하는 코드를 작성하라.

  35. 주관식 43. [실습] 주관식 · Gemini 채점

    샘플별 그룹 정보를 중첩 딕셔너리로 저장하고 sample1의 그룹을 출력하는 코드를 작성하라.

  36. 주관식 44. [실습] 주관식 · Gemini 채점

    리스트와 딕셔너리의 차이를 생물정보학 예시로 설명하라.

  37. 주관식 45. [실습] 주관식 · Gemini 채점

    유전자 이름 목록, 유전자별 발현량, 샘플별 그룹 정보를 각각 어떤 자료구조로 저장하면 좋은지 예시 코드와 함께 설명하라.

  38. 주관식 46. [실습] 주관식 · Gemini 채점

    중복 유전자 이름을 제거할 때 set을 사용할 수 있지만 순서가 중요한 경우 주의해야 하는 이유를 설명하라.

  39. 주관식 47. [실습] 주관식 · Gemini 채점

    {'S1': 'control', 'S2': 'treated'}에서 S2의 조건을 출력하는 코드를 작성하라.

  40. 주관식 48. [실습] 주관식 · Gemini 채점

    리스트와 딕셔너리가 metadata table 이해에 왜 도움이 되는지 설명하라.