국비과정에서 배운 파이썬 리스트 개념을 정리했다. 리스트 생성/인덱싱부터 연산, 슬라이싱, 주요 메소드까지 예제 위주로 다룬다.
리스트는 여러 개의 값을 순서대로 저장할 수 있는 자료형이다.
[] 안에 값을 콤마로 구분해서 넣는다.fruits = ["사과", "배", "포도", "귤"]
print("첫 번째 과일:", fruits[0]) # 인덱스 0
print("마지막 과일:", fruits[-1]) # 음수 인덱스
print("리스트 길이:", len(fruits))
# 리스트 요소 변경
fruits[1] = "바나나"
print("변경 후:", fruits)
인덱스는 0부터 시작하고, -1은 맨 마지막 요소를 가리킨다.
파이썬 리스트는 타입이 섞여 있어도 되고, 리스트 안에 리스트(중첩 리스트)도 가능하다.
data = [10, 3.14, "Python", True, [1, 2, 3]]
print("정수:", data[0])
print("실수:", data[1])
print("문자열:", data[2])
print("불:", data[3])
print("리스트 안의 리스트:", data[4][1])
for i in range(len(data))처럼 인덱스로 순회할 수도 있고, for item in data처럼 값 자체로 순회할 수도 있다.
data = [10, 3.14, "Python", True, [1, 2, 3]]
for i in range(0, len(data)):
print(f"{i}번째 인덱스의 값: {data[i]} / 타입: {type(data[i])}")
for item in data:
print(item, type(item))
리스트는 +(연결), *(반복) 연산을 지원한다.
a = [1, 2, 3]
b = [4, 5]
print("리스트 덧셈:", a + b) # [1,2,3,4,5]
print("리스트 곱셈:", b * 3) # [4,5,4,5,4,5]
print("길이:", len(a + b * 2))
nums = [10, 20, 30, 40, 50, 60]
print("앞 3개:", nums[:3]) # [10,20,30]
print("뒤 3개:", nums[-3:]) # [40,50,60]
print("짝수 인덱스만:", nums[::2]) # [10,30,50]
print("역순:", nums[::-1]) # [60,50,40,30,20,10]
리스트[시작:끝:간격]
| 항목 | 의미 | 기본값 |
|---|---|---|
| 시작 | 어디서부터 시작할지 | 0 |
| 끝 | 어디까지 가져올지 (해당 인덱스는 미포함) | 끝까지 |
| 간격(step) | 몇 칸씩 건너뛸지 | 1 |
nums = [10, 20, 30, 40, 50, 60]
print(nums[:3]) # [10, 20, 30] → 앞 3개
print(nums[2:5]) # [30, 40, 50] → 인덱스 2~4
print(nums[::2]) # [10, 30, 50] → 2칸씩 건너뛰기
print(nums[::-1]) # [60, 50, 40, 30, 20, 10] → 역순
핵심 정리
[:] → 리스트 전체 복사[::2] → 2칸씩 건너뛰며 가져오기 (짝수 번째 인덱스)[::-1] → 리스트를 역순으로 뒤집기# 0 1 2 3 4 5 6
nums = [10, 20, 30, 40, 50, 60]
# 끝까지 출력하는 세 가지 방법 (모두 동일한 결과)
print(nums)
print(nums[:])
print(nums[0:len(nums)])
| 메소드 | 설명 |
|---|---|
append(x) | 맨 뒤에 요소 추가 |
insert(i, x) | 원하는 위치에 요소 추가 |
remove(x) | 값으로 요소 제거 (앞에서 가장 가까운 것 하나만) |
pop() | 마지막 요소를 꺼내면서 제거 |
sort() | 정렬 |
reverse() | 순서 뒤집기 |
nums = [3, 1, 3, 4]
# 추가 (마지막에 추가)
nums.append(5)
print("추가 후:", nums)
# 추가 (특정 위치에 추가)
nums.insert(0, 100)
print("특정 위치 추가 후:", nums)
# 제거 - 매개변수는 '제거할 인덱스'가 아니라 '제거할 값'
# 인덱스 0에 가장 가까운 값 하나만 제거된다
nums.remove(3)
print("3 제거 후:", nums)
# 마지막 요소 꺼내오기
last = nums.pop()
print("마지막 요소:", last)
⚠️
remove(x)는 인덱스가 아니라 값을 인자로 받는다는 점 주의. 동일한 값이 여러 개면 가장 앞에 있는 것 하나만 제거된다.
scores = [88, 95, 70, 100, 99]
# 오름차순 정렬
scores.sort(reverse=False)
print("오름차순:", scores)
# 내림차순 정렬
scores.sort(reverse=True)
print("내림차순:", scores)
# 현재 순서를 그대로 뒤집기
scores.reverse()
print("역순으로 변환:", scores)
리스트 nums = [1, 2, 3, 4, 5]에서
append로 6을 추가하고remove로 3을 제거한 뒤nums = [1, 2, 3, 4, 5]
nums.append(6)
nums.remove(3)
print("리스트:", nums)
사용자에게 정수 5개를 입력받아 리스트에 저장하고, max(), min()을 이용해 최댓값과 최솟값을 출력하기.
nums = []
for i in range(5):
num = int(input(f"{i + 1}번째 정수 입력:"))
nums.append(num)
print("입력받은 숫자:", nums)
print("최댓값:", max(nums))
print("최솟값:", min(nums))
정답 코드 (while문 버전)
nums = []
count = 0
while count < 5:
num = int(input(f"{count + 1}번째 정수 입력:"))
nums.append(num)
count += 1
print("입력받은 숫자:", nums)
print("최댓값:", max(nums))
print("최솟값:", min(nums))
리스트는 파이썬에서 가장 많이 쓰이는 자료구조 중 하나다. 특히 슬라이싱([::step])과 remove()가 인덱스가 아닌 값을 받는다는 점은 실수하기 쉬우니 기억해두자.
국비과정에서 배운 파이썬 딕셔너리 개념을 정리했다. 생성/접근부터 주요 연산, 메서드, 그리고 실무에서 자주 쓰는 "딕셔너리 → 리스트 변환"까지 다룬다.
딕셔너리는 키(key)와 값(value)의 쌍으로 데이터를 저장하는 자료형이다.
{} 안에 "키:값" 형태로 정의한다.student = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
print("이름:", student["name"])
print("나이:", student["age"])
print("전공:", student["major"])
# 새로운 키-값 추가
student["grade"] = "A"
print("추가 후:", student)
값 변경과 키 추가는 같은 방식(student["키"] = 값)으로 처리한다. 이미 있는 키면 수정, 없는 키면 추가가 된다.
student = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
print("변경 전 이름:", student["name"])
student["name"] = "ROONEY"
print("변경 후 이름:", student["name"])
print("=== 키 추가 ===")
student["height"] = 177.7
print(student)
딕셔너리의 값(value)에는 리스트, 불린 등 어떤 타입도 들어갈 수 있다.
info = {
"id": 1001,
"name": "Kim",
"scores": [90, 85, 92],
"is_active": True
}
print("학생 ID:", info["id"])
print("점수 목록:", info["scores"])
print("평균 점수:", sum(info["scores"]) / len(info["scores"]))
print("활성 상태:", info["is_active"])
print("정수:", type(info["id"]))
print("리스트:", type(info["scores"]))
print("불린:", type(info["is_active"]))
| 연산 | 설명 |
|---|---|
in | 키 존재 여부 확인 |
del dict[key] | 항목 삭제 |
len(dict) | 항목 개수 확인 |
person = {"name": "Lee", "age": 30, "city": "Seoul"}
print("name 키 있나요?", "name" in person)
print("gender 키 있나요?", "gender" in person)
del person["city"]
print("삭제 후:", person)
print("길이:", len(person))
💡
in은 딕셔너리에서 키(key) 기준으로 검사한다. 값(value)이 아니라는 점 주의.
scores = {"Kim": 90, "Lee": 85, "Park": 92}
for key in scores:
print("이름:", key, "점수:", scores[key])
print("키 목록:", list(scores.keys()))
print("값 목록:", list(scores.values()))
print("키-값 쌍:", list(scores.items()))
for key in 딕셔너리로 순회하면 기본적으로 키가 나온다.
| 메서드 | 설명 |
|---|---|
get(key, default) | 키가 없으면 기본값 반환 (에러 없이 안전하게 조회) |
keys() | 모든 키 반환 |
values() | 모든 값 반환 |
items() | 모든 키-값 쌍을 튜플 형태로 반환 |
update() | 다른 딕셔너리와 병합/갱신 |
user = {"id": "admin", "pw": "1234"}
print("아이디:", user.get("id"))
print("이메일:", user.get("email", "없음")) # 없는 키 → 기본값 반환
user.update({"email": "admin@example.com", "pw": "0000"})
print("업데이트 후:", user)
user["email"]처럼 대괄호로 없는 키에 접근하면 에러가 나지만, get()은 기본값을 지정해 안전하게 처리할 수 있다.
product = {"name": "노트북", "price": 1200000, "brand": "Samsung"}
print("모든 키:", product.keys())
print("모든 값:", product.values())
print("키-값 쌍:", product.items())
for k, v in product.items():
print(f"{k} → {v}")
딕셔너리는 검색과 매핑에 강하지만, 실무에서는 정렬·필터링·시각화·데이터 전송(JSON 등) 이 필요한 경우가 많다. 이때는 순서가 있는 자료구조인 리스트로 변환해서 처리하는 게 유리하다.
주로 이런 상황에서 쓴다.
# 상품별 판매량 (딕셔너리)
sales = {"노트북": 120, "마우스": 55, "키보드": 78, "모니터": 33}
# (키, 값) 쌍을 리스트로 변환
sales_list = list(sales.items()) # 튜플들의 리스트로 변환됨
print(sales_list)
# [('노트북', 120), ('마우스', 55), ('키보드', 78), ('모니터', 33)]
# 판매량 기준 내림차순 정렬
top_sales = sorted(sales_list, key=lambda x: x[1], reverse=True)
print("판매량 순위:", top_sales)
# [('노트북', 120), ('키보드', 78), ('마우스', 55), ('모니터', 33)]
sorted()는 리스트, 딕셔너리, 튜플 등 반복 가능한(iterable) 자료형을 정렬할 때 쓰는 함수다. 정렬된 새 리스트를 반환하며 원본은 바뀌지 않는다.
sorted(iterable, key=None, reverse=False) # 정렬할 객체, 기준 키, 역순 여부
기본 예제:
numbers = [3, 1, 4, 2]
print(sorted(numbers)) # [1, 2, 3, 4] (오름차순)
print(sorted(numbers, reverse=True)) # [4, 3, 2, 1] (내림차순)
key에 lambda를 넘기면 정렬 기준을 자유롭게 지정할 수 있다.
sales_list = [("노트북", 120), ("마우스", 55), ("키보드", 78)]
# 제품명(x[0]) 기준 정렬
print(sorted(sales_list, key=lambda x: x[0]))
# [('노트북', 120), ('마우스', 55), ('키보드', 78)]
# 판매량(x[1]) 기준 내림차순 정렬
print(sorted(sales_list, key=lambda x: x[1], reverse=True))
# [('노트북', 120), ('키보드', 78), ('마우스', 55)]
# 학생 점수 데이터 (딕셔너리)
scores = {"kim": 85, "lee": 90, "park": 78, "choi": 95}
# (이름, 점수) 리스트로 변환
scores_list = list(scores.items())
# 90점 이상 학생만 필터링
passed = []
for name, score in scores_list:
if score >= 90:
passed.append((name, score))
print("합격자 명단:", passed)
# [('lee', 90), ('choi', 95)]
딕셔너리 student = {"name":"홍길동","age":20,"major":"CS"}에서
"age" 값을 1 증가시키고"grade":"A" 키-값을 추가한 뒤student = {"name": "홍길동", "age": 20, "major": "CS"}
if "age" in student:
student["age"] = student["age"] + 1
student["grade"] = "A"
print("최종 딕셔너리:", student)
사용자에게 학생 이름과 점수를 3명 입력받아 딕셔너리에 저장하고, 모든 학생의 평균 점수를 출력하기.
출력 예시
학생 점수: {'김수한': 90, '한코딩': 100, '루니': 80}
평균 점수: 90.0
정답 코드 보기
scores = {}
for i in range(3):
name = input(f"{i + 1}번째 학생 이름:")
score = int(input(f"{i + 1}번째 학생 점수:"))
scores[name] = score
print("학생 점수:", scores)
total = 0
for score in scores.values():
total += score
print("평균 점수:", total / 3.0)
print("=== 등록된 학생 명단 ===")
for name in scores.keys():
print(f"이름: {name}")
while True:
search_name = input("학생 이름 입력:")
if search_name in scores:
print(f"{search_name} 학생의 점수는 {scores[search_name]}점입니다.")
else:
print("해당 학생은 존재하지 않습니다.")
딕셔너리는 키-값 구조 덕분에 빠른 검색과 매핑에 강하지만, 정렬이나 필터링이 필요하면 list(dict.items())로 리스트(튜플 리스트)로 바꾼 뒤 sorted()를 활용하는 패턴을 기억해두면 실무에서 자주 써먹을 수 있다.
국비과정에서 배운 튜플과 세트를 정리했다. 둘 다 리스트·딕셔너리와는 다른 특성(불변성, 중복 불허)을 가진 자료형이라 언제 써야 하는지 감을 잡는 게 중요하다.
튜플은 변경 불가능(immutable) 한 자료형이다.
() 안에 값을 넣어 정의한다.fruits = ("사과", "배", "포도", "귤")
print("첫 번째 과일:", fruits[0])
print("마지막 과일:", fruits[-1])
print("길이:", len(fruits))
# 튜플은 변경 불가 → 아래 코드는 오류 발생
# fruits[1] = "바나나"
리스트와 마찬가지로 for문 순회, 인덱싱, 슬라이싱이 모두 가능하다. 다만 요소를 재할당할 수는 없다.
fruits = ("사과", "배", "포도", "귤")
print("=== for문 ===")
for fruit in fruits:
print(fruit)
print("=== 인덱싱 출력 ===")
print(fruits[0])
print("=== 슬라이싱 출력 ===")
print(fruits[0:2])
print("=== 길이 ===")
print("길이:", len(fruits))
튜플의 대표적인 활용 중 하나가 언패킹(unpacking)이다. 여러 변수에 한 번에 값을 나눠 담을 수 있다.
person = ("Alice", 25, "Seoul")
name, age, city = person
print("이름:", name)
print("나이:", age)
print("사는 곳:", city)
# 값을 교환할 때도 활용
a, b = 10, 20
a, b = b, a
print("a:", a, "b:", b)
참고로 언패킹 없이 값을 교환하려면 중간 변수가 필요하다.
a = 10
b = 20
temp = a # a의 값은 b로 대체되기 때문에 미리 보관해둬야 한다
a = b
b = temp
print("a =", a)
print("b =", b)
💡
a, b = b, a는 내부적으로 튜플을 만들어서 언패킹하는 방식이라, 중간 변수 없이 바로 값 교환이 가능하다.
| 메서드 | 설명 |
|---|---|
count(x) | 해당 값의 개수 반환 |
index(x) | 해당 값의 인덱스 반환 |
nums = (1, 2, 3, 2, 4, 2)
print("2의 개수:", nums.count(2))
print("3의 위치:", nums.index(3))
data = (1, "Python", 3.14, True)
for item in data:
print("요소:", item, "→ 타입:", type(item))
print("총 개수:", len(data))
튜플은 특히 이런 상황에서 자주 쓰인다.
def min_max(numbers):
return min(numbers), max(numbers)
result = min_max([10, 3, 7, 5, 2])
print("최솟값:", result[0])
print("최댓값:", result[1])
low, high = min_max([4, 8, 1, 9])
print("low:", low, "high:", high)
함수가 return a, b처럼 값을 여러 개 반환하면, 실제로는 튜플 하나가 반환되는 것이다.
point = (3, 5)
print("x 좌표:", point[0])
print("y 좌표:", point[1])
# 언패킹
x, y = point
print(f"좌표는 ({x}, {y}) 입니다.")
세트는 중복을 허용하지 않고 순서가 없는 집합 자료형이다.
{} 또는 set()으로 생성한다.s = {1, 2, 3, 3, 4, 4, 5}
print("세트:", s) # 중복 제거됨
s.add(6)
print("추가 후:", s)
# 인덱스가 아니라 '값'을 찾아서 삭제한다
s.remove(3)
print("삭제 후:", s)
⚠️ 세트는 순서가 없기 때문에 인덱싱(
s[0])이 불가능하다.remove()도 인덱스가 아니라 값으로 지운다.
문자열도 set()으로 감싸면 중복 없는 문자 집합이 된다.
text = "hello"
letters = set(text)
print("문자 집합:", letters)
print("길이:", len(letters))
letters.add("z")
print("추가 후:", letters)
| 연산 | 연산자 | 메서드 |
|---|---|---|
| 합집합 | \| | union() |
| 교집합 | & | intersection() |
| 차집합 | - | difference() |
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print("=== 합집합 ===")
print(a | b)
print(a.union(b))
print("=== 교집합 ===")
print(a & b)
print(a.intersection(b))
print("=== 차집합 ===")
print(a - b)
print(a.difference(b))
x = {10, 20, 30}
y = {30, 40, 50}
print("합집합:", x.union(y))
print("교집합:", x.intersection(y))
print("차집합:", x.difference(y))
| 메서드 | 설명 |
|---|---|
add(x) | 원소 추가 |
remove(x) | 원소 제거 (없으면 오류 발생) |
discard(x) | 원소 제거 (없어도 오류 없음) |
clear() | 전체 비우기 |
s = {1, 2, 3}
s.add(4)
print("add:", s)
s.remove(2)
print("remove:", s)
s.discard(10) # 없는 값이지만 오류 발생하지 않음
print("discard 후:", s)
💡 있을지 없을지 모르는 값을 안전하게 지우고 싶다면
remove()보다discard()가 낫다.
numbers = {100, 200, 300}
print("초기 세트:", numbers)
numbers.clear()
print("clear 후:", numbers)
튜플 (10, 20, 30, 40, 50)에서
count와 index 메서드를 각각 사용해보기t = (10, 20, 30, 40, 50)
print("세 번째 요소:", t[2])
print("30의 갯수:", t.count(30))
print("40의 위치:", t.index(40))
반 A와 반 B의 학생들이 수강하는 과목을 각각 3개씩 입력받아 세트로 저장한 뒤, 두 반 모두 수강하는 공통 과목(교집합)을 출력하기.
정답 코드 보기a_subjects = set()
b_subjects = set()
print("A반 수강 과목")
for i in range(3):
subject = input("수강 과목: ")
a_subjects.add(subject)
print("B반 수강 과목")
for i in range(3):
subject = input("수강 과목: ")
b_subjects.add(subject)
print("두 학급의 공통 수강 과목:", a_subjects.intersection(b_subjects))
리스트가 "순서 있고 변경 가능"하다면, 튜플은 "순서 있고 변경 불가", 세트는 "순서 없고 중복 불가"라는 식으로 셋을 대조해서 기억하면 헷갈리지 않는다.